@acorex/components 21.0.0-next.3 → 21.0.0-next.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/accordion/index.d.ts +0 -1
- package/autocomplete/index.d.ts +23 -9
- package/button/index.d.ts +38 -17
- package/chips/index.d.ts +3 -8
- package/code-editor/README.md +291 -1
- package/code-editor/index.d.ts +260 -12
- package/command/index.d.ts +1 -0
- package/conversation2/README.md +426 -0
- package/conversation2/index.d.ts +6139 -0
- package/data-table/index.d.ts +79 -7
- package/dialog/index.d.ts +1 -1
- package/drawer/README.md +2 -2
- package/drawer/index.d.ts +33 -57
- package/drawer-legacy/README.md +3 -0
- package/drawer-legacy/index.d.ts +86 -0
- package/editor/README.md +3 -0
- package/editor/index.d.ts +79 -0
- package/fesm2022/acorex-components-accordion.mjs +19 -24
- package/fesm2022/acorex-components-accordion.mjs.map +1 -1
- package/fesm2022/acorex-components-action-sheet.mjs +12 -12
- package/fesm2022/acorex-components-action-sheet.mjs.map +1 -1
- package/fesm2022/acorex-components-alert.mjs +14 -14
- package/fesm2022/acorex-components-alert.mjs.map +1 -1
- package/fesm2022/acorex-components-aspect-ratio.mjs +4 -4
- package/fesm2022/acorex-components-aspect-ratio.mjs.map +1 -1
- package/fesm2022/acorex-components-audio-wave.mjs +12 -11
- package/fesm2022/acorex-components-audio-wave.mjs.map +1 -1
- package/fesm2022/acorex-components-autocomplete.mjs +30 -13
- package/fesm2022/acorex-components-autocomplete.mjs.map +1 -1
- package/fesm2022/acorex-components-avatar.mjs +13 -13
- package/fesm2022/acorex-components-avatar.mjs.map +1 -1
- package/fesm2022/acorex-components-badge.mjs +10 -10
- package/fesm2022/acorex-components-badge.mjs.map +1 -1
- package/fesm2022/acorex-components-bottom-navigation.mjs +12 -12
- package/fesm2022/acorex-components-bottom-navigation.mjs.map +1 -1
- package/fesm2022/acorex-components-breadcrumbs.mjs +12 -12
- package/fesm2022/acorex-components-breadcrumbs.mjs.map +1 -1
- package/fesm2022/acorex-components-button-group.mjs +17 -19
- package/fesm2022/acorex-components-button-group.mjs.map +1 -1
- package/fesm2022/acorex-components-button.mjs +78 -29
- package/fesm2022/acorex-components-button.mjs.map +1 -1
- package/fesm2022/acorex-components-calendar.mjs +18 -18
- package/fesm2022/acorex-components-calendar.mjs.map +1 -1
- package/fesm2022/acorex-components-check-box.mjs +11 -11
- package/fesm2022/acorex-components-check-box.mjs.map +1 -1
- package/fesm2022/acorex-components-chips.mjs +12 -14
- package/fesm2022/acorex-components-chips.mjs.map +1 -1
- package/fesm2022/acorex-components-circular-progress.mjs +13 -11
- package/fesm2022/acorex-components-circular-progress.mjs.map +1 -1
- package/fesm2022/acorex-components-code-editor.mjs +494 -162
- package/fesm2022/acorex-components-code-editor.mjs.map +1 -1
- package/fesm2022/acorex-components-collapse.mjs +13 -28
- package/fesm2022/acorex-components-collapse.mjs.map +1 -1
- package/fesm2022/acorex-components-color-box.mjs +11 -11
- package/fesm2022/acorex-components-color-box.mjs.map +1 -1
- package/fesm2022/acorex-components-color-palette.mjs +32 -32
- package/fesm2022/acorex-components-color-palette.mjs.map +1 -1
- package/fesm2022/acorex-components-command.mjs +18 -11
- package/fesm2022/acorex-components-command.mjs.map +1 -1
- package/fesm2022/acorex-components-comment.mjs +34 -34
- package/fesm2022/acorex-components-comment.mjs.map +1 -1
- package/fesm2022/acorex-components-conversation.mjs +56 -65
- package/fesm2022/acorex-components-conversation.mjs.map +1 -1
- package/fesm2022/acorex-components-conversation2.mjs +17641 -0
- package/fesm2022/acorex-components-conversation2.mjs.map +1 -0
- package/fesm2022/acorex-components-cron-job.mjs +53 -53
- package/fesm2022/acorex-components-cron-job.mjs.map +1 -1
- package/fesm2022/acorex-components-data-list.mjs +5 -5
- package/fesm2022/acorex-components-data-list.mjs.map +1 -1
- package/fesm2022/acorex-components-data-pager.mjs +53 -41
- package/fesm2022/acorex-components-data-pager.mjs.map +1 -1
- package/fesm2022/acorex-components-data-table.mjs +462 -105
- package/fesm2022/acorex-components-data-table.mjs.map +1 -1
- package/fesm2022/acorex-components-datetime-box.mjs +10 -10
- package/fesm2022/acorex-components-datetime-box.mjs.map +1 -1
- package/fesm2022/acorex-components-datetime-input.mjs +8 -8
- package/fesm2022/acorex-components-datetime-input.mjs.map +1 -1
- package/fesm2022/acorex-components-datetime-picker.mjs +11 -11
- package/fesm2022/acorex-components-datetime-picker.mjs.map +1 -1
- package/fesm2022/acorex-components-decorators.mjs +96 -54
- package/fesm2022/acorex-components-decorators.mjs.map +1 -1
- package/fesm2022/acorex-components-dialog.mjs +26 -16
- package/fesm2022/acorex-components-dialog.mjs.map +1 -1
- package/fesm2022/acorex-components-drawer-legacy.mjs +218 -0
- package/fesm2022/acorex-components-drawer-legacy.mjs.map +1 -0
- package/fesm2022/acorex-components-drawer.mjs +66 -150
- package/fesm2022/acorex-components-drawer.mjs.map +1 -1
- package/fesm2022/acorex-components-dropdown-button.mjs +9 -9
- package/fesm2022/acorex-components-dropdown-button.mjs.map +1 -1
- package/fesm2022/acorex-components-dropdown.mjs +18 -16
- package/fesm2022/acorex-components-dropdown.mjs.map +1 -1
- package/fesm2022/acorex-components-editor.mjs +195 -0
- package/fesm2022/acorex-components-editor.mjs.map +1 -0
- package/fesm2022/acorex-components-file-explorer.mjs +28 -28
- package/fesm2022/acorex-components-file-explorer.mjs.map +1 -1
- package/fesm2022/acorex-components-flow-chart.mjs +18 -18
- package/fesm2022/acorex-components-flow-chart.mjs.map +1 -1
- package/fesm2022/acorex-components-form.mjs +52 -35
- package/fesm2022/acorex-components-form.mjs.map +1 -1
- package/fesm2022/acorex-components-grid-layout-builder.mjs +14 -15
- package/fesm2022/acorex-components-grid-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-components-image-editor.mjs +166 -126
- package/fesm2022/acorex-components-image-editor.mjs.map +1 -1
- package/fesm2022/acorex-components-image.mjs +10 -10
- package/fesm2022/acorex-components-image.mjs.map +1 -1
- package/fesm2022/acorex-components-json-viewer.mjs +9 -9
- package/fesm2022/acorex-components-json-viewer.mjs.map +1 -1
- package/fesm2022/acorex-components-kanban.mjs +9 -7
- package/fesm2022/acorex-components-kanban.mjs.map +1 -1
- package/fesm2022/acorex-components-kbd.mjs +8 -8
- package/fesm2022/acorex-components-kbd.mjs.map +1 -1
- package/fesm2022/acorex-components-label.mjs +9 -9
- package/fesm2022/acorex-components-label.mjs.map +1 -1
- package/fesm2022/acorex-components-list.mjs +10 -10
- package/fesm2022/acorex-components-list.mjs.map +1 -1
- package/fesm2022/acorex-components-loading-dialog.mjs +22 -13
- package/fesm2022/acorex-components-loading-dialog.mjs.map +1 -1
- package/fesm2022/acorex-components-loading.mjs +23 -23
- package/fesm2022/acorex-components-loading.mjs.map +1 -1
- package/fesm2022/acorex-components-map.mjs +16 -15
- package/fesm2022/acorex-components-map.mjs.map +1 -1
- package/fesm2022/acorex-components-media-viewer.mjs +78 -97
- package/fesm2022/acorex-components-media-viewer.mjs.map +1 -1
- package/fesm2022/acorex-components-menu.mjs +24 -24
- package/fesm2022/acorex-components-menu.mjs.map +1 -1
- package/fesm2022/{acorex-components-modal-acorex-components-modal-h5Y-qcbh.mjs → acorex-components-modal-acorex-components-modal-BmmAkCKJ.mjs} +24 -24
- package/fesm2022/acorex-components-modal-acorex-components-modal-BmmAkCKJ.mjs.map +1 -0
- package/fesm2022/acorex-components-modal-modal-content.component-5GqTzNOs.mjs +214 -0
- package/fesm2022/acorex-components-modal-modal-content.component-5GqTzNOs.mjs.map +1 -0
- package/fesm2022/acorex-components-modal.mjs +1 -1
- package/fesm2022/acorex-components-navbar.mjs +9 -9
- package/fesm2022/acorex-components-navbar.mjs.map +1 -1
- package/fesm2022/acorex-components-notification.mjs +16 -23
- package/fesm2022/acorex-components-notification.mjs.map +1 -1
- package/fesm2022/acorex-components-number-box-legacy.mjs +412 -0
- package/fesm2022/acorex-components-number-box-legacy.mjs.map +1 -0
- package/fesm2022/acorex-components-number-box.mjs +98 -331
- package/fesm2022/acorex-components-number-box.mjs.map +1 -1
- package/fesm2022/acorex-components-otp.mjs +10 -10
- package/fesm2022/acorex-components-otp.mjs.map +1 -1
- package/fesm2022/acorex-components-page.mjs +10 -10
- package/fesm2022/acorex-components-page.mjs.map +1 -1
- package/fesm2022/acorex-components-paint.mjs +35 -40
- package/fesm2022/acorex-components-paint.mjs.map +1 -1
- package/fesm2022/acorex-components-password-box.mjs +13 -13
- package/fesm2022/acorex-components-password-box.mjs.map +1 -1
- package/fesm2022/acorex-components-pdf-reader.mjs +8 -8
- package/fesm2022/acorex-components-pdf-reader.mjs.map +1 -1
- package/fesm2022/acorex-components-phone-box.mjs +10 -10
- package/fesm2022/acorex-components-phone-box.mjs.map +1 -1
- package/fesm2022/acorex-components-picker.mjs +17 -17
- package/fesm2022/acorex-components-picker.mjs.map +1 -1
- package/fesm2022/acorex-components-popover.mjs +12 -12
- package/fesm2022/acorex-components-popover.mjs.map +1 -1
- package/fesm2022/acorex-components-popup.mjs +13 -13
- package/fesm2022/acorex-components-popup.mjs.map +1 -1
- package/fesm2022/acorex-components-progress-bar.mjs +11 -9
- package/fesm2022/acorex-components-progress-bar.mjs.map +1 -1
- package/fesm2022/acorex-components-qrcode.mjs +8 -8
- package/fesm2022/acorex-components-qrcode.mjs.map +1 -1
- package/fesm2022/acorex-components-query-builder.mjs +9 -9
- package/fesm2022/acorex-components-query-builder.mjs.map +1 -1
- package/fesm2022/acorex-components-radio.mjs +7 -7
- package/fesm2022/acorex-components-radio.mjs.map +1 -1
- package/fesm2022/acorex-components-rail-navigation.mjs +40 -38
- package/fesm2022/acorex-components-rail-navigation.mjs.map +1 -1
- package/fesm2022/acorex-components-range-slider.mjs +11 -11
- package/fesm2022/acorex-components-range-slider.mjs.map +1 -1
- package/fesm2022/acorex-components-rate-picker.mjs +20 -35
- package/fesm2022/acorex-components-rate-picker.mjs.map +1 -1
- package/fesm2022/acorex-components-rest-api-generator.mjs +23 -23
- package/fesm2022/acorex-components-rest-api-generator.mjs.map +1 -1
- package/fesm2022/acorex-components-result.mjs +8 -8
- package/fesm2022/acorex-components-result.mjs.map +1 -1
- package/fesm2022/acorex-components-routing-progress.mjs +8 -8
- package/fesm2022/acorex-components-routing-progress.mjs.map +1 -1
- package/fesm2022/acorex-components-rrule.mjs +111 -16
- package/fesm2022/acorex-components-rrule.mjs.map +1 -1
- package/fesm2022/acorex-components-scheduler-picker.mjs +2339 -0
- package/fesm2022/acorex-components-scheduler-picker.mjs.map +1 -0
- package/fesm2022/acorex-components-scheduler.mjs +52 -52
- package/fesm2022/acorex-components-scheduler.mjs.map +1 -1
- package/fesm2022/acorex-components-scss.mjs +4 -4
- package/fesm2022/acorex-components-scss.mjs.map +1 -1
- package/fesm2022/acorex-components-search-box.mjs +23 -12
- package/fesm2022/acorex-components-search-box.mjs.map +1 -1
- package/fesm2022/acorex-components-select-box.mjs +36 -17
- package/fesm2022/acorex-components-select-box.mjs.map +1 -1
- package/fesm2022/acorex-components-selection-list-2.mjs +10 -10
- package/fesm2022/acorex-components-selection-list-2.mjs.map +1 -1
- package/fesm2022/acorex-components-selection-list.mjs +10 -10
- package/fesm2022/acorex-components-selection-list.mjs.map +1 -1
- package/fesm2022/acorex-components-side-menu.mjs +31 -38
- package/fesm2022/acorex-components-side-menu.mjs.map +1 -1
- package/fesm2022/acorex-components-skeleton.mjs +8 -8
- package/fesm2022/acorex-components-skeleton.mjs.map +1 -1
- package/fesm2022/acorex-components-slider.mjs +11 -11
- package/fesm2022/acorex-components-slider.mjs.map +1 -1
- package/fesm2022/acorex-components-sliding-item.mjs +17 -17
- package/fesm2022/acorex-components-sliding-item.mjs.map +1 -1
- package/fesm2022/acorex-components-step-wizard.mjs +16 -16
- package/fesm2022/acorex-components-step-wizard.mjs.map +1 -1
- package/fesm2022/acorex-components-switch.mjs +14 -14
- package/fesm2022/acorex-components-switch.mjs.map +1 -1
- package/fesm2022/acorex-components-tabs.mjs +20 -16
- package/fesm2022/acorex-components-tabs.mjs.map +1 -1
- package/fesm2022/acorex-components-tag-box.mjs +51 -21
- package/fesm2022/acorex-components-tag-box.mjs.map +1 -1
- package/fesm2022/acorex-components-tag.mjs +47 -11
- package/fesm2022/acorex-components-tag.mjs.map +1 -1
- package/fesm2022/acorex-components-text-area.mjs +9 -9
- package/fesm2022/acorex-components-text-area.mjs.map +1 -1
- package/fesm2022/acorex-components-text-box.mjs +13 -13
- package/fesm2022/acorex-components-text-box.mjs.map +1 -1
- package/fesm2022/acorex-components-time-duration.mjs +54 -14
- package/fesm2022/acorex-components-time-duration.mjs.map +1 -1
- package/fesm2022/acorex-components-time-line.mjs +14 -29
- package/fesm2022/acorex-components-time-line.mjs.map +1 -1
- package/fesm2022/acorex-components-toast.mjs +14 -14
- package/fesm2022/acorex-components-toast.mjs.map +1 -1
- package/fesm2022/acorex-components-toolbar.mjs +9 -9
- package/fesm2022/acorex-components-toolbar.mjs.map +1 -1
- package/fesm2022/acorex-components-tooltip.mjs +12 -12
- package/fesm2022/acorex-components-tooltip.mjs.map +1 -1
- package/fesm2022/acorex-components-tree-view.mjs +16 -45
- package/fesm2022/acorex-components-tree-view.mjs.map +1 -1
- package/fesm2022/acorex-components-tree2.mjs +689 -0
- package/fesm2022/acorex-components-tree2.mjs.map +1 -0
- package/fesm2022/acorex-components-uploader.mjs +28 -641
- package/fesm2022/acorex-components-uploader.mjs.map +1 -1
- package/fesm2022/acorex-components-video-player.mjs +8 -8
- package/fesm2022/acorex-components-video-player.mjs.map +1 -1
- package/fesm2022/acorex-components-wysiwyg.mjs +213 -462
- package/fesm2022/acorex-components-wysiwyg.mjs.map +1 -1
- package/fesm2022/acorex-components.mjs.map +1 -1
- package/form/index.d.ts +3 -3
- package/grid-layout-builder/index.d.ts +1 -2
- package/image-editor/index.d.ts +8 -5
- package/loading/index.d.ts +1 -1
- package/media-viewer/index.d.ts +2 -3
- package/notification/index.d.ts +0 -2
- package/number-box/README.md +2 -2
- package/number-box/index.d.ts +31 -171
- package/number-box-legacy/README.md +3 -0
- package/number-box-legacy/index.d.ts +191 -0
- package/package.json +53 -26
- package/paint/index.d.ts +1 -6
- package/phone-box/index.d.ts +4 -4
- package/rate-picker/index.d.ts +5 -15
- package/rrule/index.d.ts +96 -1
- package/scheduler-picker/README.md +15 -0
- package/scheduler-picker/index.d.ts +1360 -0
- package/search-box/index.d.ts +6 -1
- package/select-box/index.d.ts +15 -10
- package/side-menu/index.d.ts +3 -2
- package/tag/index.d.ts +8 -2
- package/tag-box/index.d.ts +12 -3
- package/time-duration/index.d.ts +19 -3
- package/tree2/README.md +3 -0
- package/tree2/index.d.ts +337 -0
- package/uploader/index.d.ts +4 -331
- package/wysiwyg/index.d.ts +57 -159
- package/drawer-2/README.md +0 -3
- package/drawer-2/index.d.ts +0 -62
- package/fesm2022/acorex-components-drawer-2.mjs +0 -134
- package/fesm2022/acorex-components-drawer-2.mjs.map +0 -1
- package/fesm2022/acorex-components-modal-acorex-components-modal-h5Y-qcbh.mjs.map +0 -1
- package/fesm2022/acorex-components-modal-modal-content.component-B6tyMLdU.mjs +0 -235
- package/fesm2022/acorex-components-modal-modal-content.component-B6tyMLdU.mjs.map +0 -1
- package/fesm2022/acorex-components-number-box-2.mjs +0 -183
- package/fesm2022/acorex-components-number-box-2.mjs.map +0 -1
- package/number-box-2/README.md +0 -3
- package/number-box-2/index.d.ts +0 -41
|
@@ -0,0 +1,2339 @@
|
|
|
1
|
+
import { MXValueComponent, AXComponent, AXFocusableComponent, AXValuableComponent } from '@acorex/cdk/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { input, output, ViewEncapsulation, ChangeDetectionStrategy, Component, signal, effect, computed, InjectionToken, inject, Injectable, forwardRef } from '@angular/core';
|
|
4
|
+
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
5
|
+
import { AXSwitchComponent } from '@acorex/components/switch';
|
|
6
|
+
import { AXTranslatorPipe, AXTranslationService } from '@acorex/core/translation';
|
|
7
|
+
import { AsyncPipe, DatePipe } from '@angular/common';
|
|
8
|
+
import { AXNumberBoxComponent } from '@acorex/components/number-box';
|
|
9
|
+
import { AXSelectBoxComponent } from '@acorex/components/select-box';
|
|
10
|
+
import * as i1 from '@acorex/components/selection-list';
|
|
11
|
+
import { AXSelectionListModule } from '@acorex/components/selection-list';
|
|
12
|
+
import { AXDateTimeBoxComponent } from '@acorex/components/datetime-box';
|
|
13
|
+
import * as i2 from '@acorex/components/badge';
|
|
14
|
+
import { AXBadgeModule } from '@acorex/components/badge';
|
|
15
|
+
import { AXButtonComponent } from '@acorex/components/button';
|
|
16
|
+
import * as i3 from '@acorex/components/chips';
|
|
17
|
+
import { AXChipsModule } from '@acorex/components/chips';
|
|
18
|
+
import * as i1$1 from '@acorex/components/decorators';
|
|
19
|
+
import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Interval selector component
|
|
23
|
+
* Allows user to select "Every X [units]"
|
|
24
|
+
*/
|
|
25
|
+
class AXSchedulerPickerIntervalSelectorComponent {
|
|
26
|
+
constructor() {
|
|
27
|
+
/**
|
|
28
|
+
* Current interval value
|
|
29
|
+
*/
|
|
30
|
+
this.interval = input.required(...(ngDevMode ? [{ debugName: "interval" }] : []));
|
|
31
|
+
/**
|
|
32
|
+
* Configuration
|
|
33
|
+
*/
|
|
34
|
+
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
35
|
+
/**
|
|
36
|
+
* Emits when interval changes
|
|
37
|
+
*/
|
|
38
|
+
this.intervalChange = output();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Handle interval value change
|
|
42
|
+
*/
|
|
43
|
+
onIntervalChange(value) {
|
|
44
|
+
if (value && value > 0) {
|
|
45
|
+
this.intervalChange.emit(value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get unit translation key based on mode
|
|
50
|
+
*/
|
|
51
|
+
getUnitKey() {
|
|
52
|
+
const mode = this.config().mode;
|
|
53
|
+
const pluralKey = this.interval() === 1 ? 'singular' : 'plural';
|
|
54
|
+
switch (mode) {
|
|
55
|
+
case 'hourly':
|
|
56
|
+
return `@acorex:schedulerPicker.units.hour.${pluralKey}`;
|
|
57
|
+
case 'daily':
|
|
58
|
+
return `@acorex:schedulerPicker.units.day.${pluralKey}`;
|
|
59
|
+
case 'weekly':
|
|
60
|
+
return `@acorex:schedulerPicker.units.week.${pluralKey}`;
|
|
61
|
+
case 'monthly':
|
|
62
|
+
return `@acorex:schedulerPicker.units.month.${pluralKey}`;
|
|
63
|
+
case 'yearly':
|
|
64
|
+
return `@acorex:schedulerPicker.units.year.${pluralKey}`;
|
|
65
|
+
default:
|
|
66
|
+
return '@acorex:schedulerPicker.units.day.plural';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerIntervalSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
70
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: AXSchedulerPickerIntervalSelectorComponent, isStandalone: true, selector: "ax-scheduler-picker-interval-selector", inputs: { interval: { classPropertyName: "interval", publicName: "interval", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { intervalChange: "intervalChange" }, ngImport: i0, template: "<div class=\"ax-scheduler-picker-interval-selector\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.repeatEvery' | translate | async }}\n </label>\n <div class=\"ax-scheduler-picker-interval-input-group\">\n <ax-number-box\n [value]=\"interval()\"\n [minValue]=\"config().minInterval || 1\"\n [maxValue]=\"config().maxInterval || 999\"\n [disabled]=\"false\"\n (valueChange)=\"onIntervalChange($event)\"\n />\n <span class=\"ax-scheduler-picker-interval-unit\">\n {{ getUnitKey() | translate | async }}\n </span>\n </div>\n</div>\n", styles: [".ax-scheduler-picker-interval-selector{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}.ax-scheduler-picker-interval-input-group{display:flex;align-items:center;gap:.375rem}.ax-scheduler-picker-interval-input-group ax-number-box{width:80px}.ax-scheduler-picker-interval-input-group .ax-scheduler-picker-interval-unit{color:var(--ax-comp-scheduler-picker-label-color);font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: AXNumberBoxComponent, selector: "ax-number-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "minValue", "maxValue", "showSpinButtons", "thousandsSeparator", "decimals", "changeOnScroll", "step"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "thousandsSeparatorChange"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
71
|
+
}
|
|
72
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerIntervalSelectorComponent, decorators: [{
|
|
73
|
+
type: Component,
|
|
74
|
+
args: [{ selector: 'ax-scheduler-picker-interval-selector', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [FormsModule, AXNumberBoxComponent, AXTranslatorPipe, AsyncPipe], template: "<div class=\"ax-scheduler-picker-interval-selector\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.repeatEvery' | translate | async }}\n </label>\n <div class=\"ax-scheduler-picker-interval-input-group\">\n <ax-number-box\n [value]=\"interval()\"\n [minValue]=\"config().minInterval || 1\"\n [maxValue]=\"config().maxInterval || 999\"\n [disabled]=\"false\"\n (valueChange)=\"onIntervalChange($event)\"\n />\n <span class=\"ax-scheduler-picker-interval-unit\">\n {{ getUnitKey() | translate | async }}\n </span>\n </div>\n</div>\n", styles: [".ax-scheduler-picker-interval-selector{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}.ax-scheduler-picker-interval-input-group{display:flex;align-items:center;gap:.375rem}.ax-scheduler-picker-interval-input-group ax-number-box{width:80px}.ax-scheduler-picker-interval-input-group .ax-scheduler-picker-interval-unit{color:var(--ax-comp-scheduler-picker-label-color);font-size:.875rem}\n"] }]
|
|
75
|
+
}], propDecorators: { interval: [{ type: i0.Input, args: [{ isSignal: true, alias: "interval", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], intervalChange: [{ type: i0.Output, args: ["intervalChange"] }] } });
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Constants for scheduler picker module
|
|
79
|
+
*/
|
|
80
|
+
/**
|
|
81
|
+
* Days of the week (0-6: Sunday-Saturday)
|
|
82
|
+
*/
|
|
83
|
+
const AX_SCHEDULER_PICKER_DAYS_OF_WEEK = Object.freeze([
|
|
84
|
+
{ id: 0, text: 'Sunday', key: 'sunday', rruleKey: 'SU' },
|
|
85
|
+
{ id: 1, text: 'Monday', key: 'monday', rruleKey: 'MO' },
|
|
86
|
+
{ id: 2, text: 'Tuesday', key: 'tuesday', rruleKey: 'TU' },
|
|
87
|
+
{ id: 3, text: 'Wednesday', key: 'wednesday', rruleKey: 'WE' },
|
|
88
|
+
{ id: 4, text: 'Thursday', key: 'thursday', rruleKey: 'TH' },
|
|
89
|
+
{ id: 5, text: 'Friday', key: 'friday', rruleKey: 'FR' },
|
|
90
|
+
{ id: 6, text: 'Saturday', key: 'saturday', rruleKey: 'SA' },
|
|
91
|
+
]);
|
|
92
|
+
/**
|
|
93
|
+
* Months of the year (0-11: January-December)
|
|
94
|
+
*/
|
|
95
|
+
const AX_SCHEDULER_PICKER_MONTHS = Object.freeze([
|
|
96
|
+
{ id: 0, text: 'January', key: 'january' },
|
|
97
|
+
{ id: 1, text: 'February', key: 'february' },
|
|
98
|
+
{ id: 2, text: 'March', key: 'march' },
|
|
99
|
+
{ id: 3, text: 'April', key: 'april' },
|
|
100
|
+
{ id: 4, text: 'May', key: 'may' },
|
|
101
|
+
{ id: 5, text: 'June', key: 'june' },
|
|
102
|
+
{ id: 6, text: 'July', key: 'july' },
|
|
103
|
+
{ id: 7, text: 'August', key: 'august' },
|
|
104
|
+
{ id: 8, text: 'September', key: 'september' },
|
|
105
|
+
{ id: 9, text: 'October', key: 'october' },
|
|
106
|
+
{ id: 10, text: 'November', key: 'november' },
|
|
107
|
+
{ id: 11, text: 'December', key: 'december' },
|
|
108
|
+
]);
|
|
109
|
+
/**
|
|
110
|
+
* Occurrence positions (1st, 2nd, 3rd, 4th, Last)
|
|
111
|
+
*/
|
|
112
|
+
const AX_SCHEDULER_PICKER_OCCURRENCE_POSITIONS = Object.freeze([
|
|
113
|
+
{ value: 1, text: 'First', key: 'first' },
|
|
114
|
+
{ value: 2, text: 'Second', key: 'second' },
|
|
115
|
+
{ value: 3, text: 'Third', key: 'third' },
|
|
116
|
+
{ value: 4, text: 'Fourth', key: 'fourth' },
|
|
117
|
+
{ value: -1, text: 'Last', key: 'last' },
|
|
118
|
+
]);
|
|
119
|
+
/**
|
|
120
|
+
* RRule day keys mapping (for RRule library)
|
|
121
|
+
*/
|
|
122
|
+
const AX_SCHEDULER_PICKER_RRULE_DAY_KEYS = Object.freeze(AX_SCHEDULER_PICKER_DAYS_OF_WEEK.map((d) => d.rruleKey));
|
|
123
|
+
/**
|
|
124
|
+
* Translation keys for days of week
|
|
125
|
+
*/
|
|
126
|
+
const AX_SCHEDULER_PICKER_DAY_TRANSLATION_KEYS = Object.freeze(AX_SCHEDULER_PICKER_DAYS_OF_WEEK.map((d) => d.key));
|
|
127
|
+
/**
|
|
128
|
+
* Translation keys for months
|
|
129
|
+
*/
|
|
130
|
+
const AX_SCHEDULER_PICKER_MONTH_TRANSLATION_KEYS = Object.freeze(AX_SCHEDULER_PICKER_MONTHS.map((m) => m.key));
|
|
131
|
+
/**
|
|
132
|
+
* Default first day of week (0 = Sunday)
|
|
133
|
+
*/
|
|
134
|
+
const AX_SCHEDULER_PICKER_DEFAULT_FIRST_DAY_OF_WEEK = 0;
|
|
135
|
+
/**
|
|
136
|
+
* Default time format
|
|
137
|
+
*/
|
|
138
|
+
const AX_SCHEDULER_PICKER_DEFAULT_TIME_FORMAT = '24h';
|
|
139
|
+
/**
|
|
140
|
+
* Default time precision
|
|
141
|
+
*/
|
|
142
|
+
const AX_SCHEDULER_PICKER_DEFAULT_TIME_PRECISION = 'minutes';
|
|
143
|
+
/**
|
|
144
|
+
* Default locale
|
|
145
|
+
*/
|
|
146
|
+
const AX_SCHEDULER_PICKER_DEFAULT_LOCALE = 'en-US';
|
|
147
|
+
/**
|
|
148
|
+
* Weekday range for daily mode (Monday-Friday)
|
|
149
|
+
*/
|
|
150
|
+
const AX_SCHEDULER_PICKER_WEEKDAY_START = 1; // Monday
|
|
151
|
+
const AX_SCHEDULER_PICKER_WEEKDAY_END = 5; // Friday
|
|
152
|
+
/**
|
|
153
|
+
* Default occurrences count for end condition
|
|
154
|
+
*/
|
|
155
|
+
const AX_SCHEDULER_PICKER_DEFAULT_OCCURRENCES = 10;
|
|
156
|
+
|
|
157
|
+
class AXSchedulerPickerDailyPanelComponent {
|
|
158
|
+
constructor() {
|
|
159
|
+
this.pattern = input.required(...(ngDevMode ? [{ debugName: "pattern" }] : []));
|
|
160
|
+
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
161
|
+
this.patternChange = output();
|
|
162
|
+
this.weekdayOnly = signal(false, ...(ngDevMode ? [{ debugName: "weekdayOnly" }] : []));
|
|
163
|
+
// Initialize weekdayOnly from pattern
|
|
164
|
+
effect(() => {
|
|
165
|
+
const pattern = this.pattern();
|
|
166
|
+
if (pattern?.recurrence?.byDay) {
|
|
167
|
+
// Check if byDay is [1,2,3,4,5] (weekdays only)
|
|
168
|
+
const isWeekdaysOnly = pattern.recurrence.byDay.length === 5 &&
|
|
169
|
+
pattern.recurrence.byDay.every((d) => d >= AX_SCHEDULER_PICKER_WEEKDAY_START && d <= AX_SCHEDULER_PICKER_WEEKDAY_END);
|
|
170
|
+
this.weekdayOnly.set(isWeekdaysOnly);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
onIntervalChange(interval) {
|
|
175
|
+
this.patternChange.emit({ interval });
|
|
176
|
+
}
|
|
177
|
+
onWeekdayOnlyChange(value) {
|
|
178
|
+
this.weekdayOnly.set(value);
|
|
179
|
+
// Emit recurrence with weekday filter (Mon-Fri)
|
|
180
|
+
this.patternChange.emit({
|
|
181
|
+
recurrence: {
|
|
182
|
+
...this.pattern()?.recurrence,
|
|
183
|
+
byDay: value ? [AX_SCHEDULER_PICKER_WEEKDAY_START, 2, 3, 4, AX_SCHEDULER_PICKER_WEEKDAY_END] : undefined,
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerDailyPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
188
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerDailyPanelComponent, isStandalone: true, selector: "ax-scheduler-picker-daily-panel", inputs: { pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { patternChange: "patternChange" }, ngImport: i0, template: "<div class=\"ax-scheduler-picker-daily-panel\">\n <!-- Interval selector -->\n @if (config().options?.showInterval) {\n <ax-scheduler-picker-interval-selector\n [interval]=\"pattern()?.interval || 1\"\n [config]=\"config()\"\n (intervalChange)=\"onIntervalChange($event)\"\n />\n }\n\n <!-- Weekdays only switch -->\n @if (config().options?.showWeekdaysOnly) {\n <div class=\"ax-scheduler-picker-weekdays-only\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.weekdaysOnly' | translate | async }}\n </label>\n <ax-switch [value]=\"weekdayOnly()\" (valueChange)=\"onWeekdayOnlyChange($event)\" />\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-daily-panel{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-weekday-option{display:flex;align-items:center;justify-content:space-between;padding:.25rem 0}.ax-scheduler-picker-time-selection{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: AXSwitchComponent, selector: "ax-switch", inputs: ["disabled", "readonly", "color", "tabIndex", "value", "name", "isLoading"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged", "readonlyChange", "disabledChange"] }, { kind: "component", type: AXSchedulerPickerIntervalSelectorComponent, selector: "ax-scheduler-picker-interval-selector", inputs: ["interval", "config"], outputs: ["intervalChange"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
189
|
+
}
|
|
190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerDailyPanelComponent, decorators: [{
|
|
191
|
+
type: Component,
|
|
192
|
+
args: [{ selector: 'ax-scheduler-picker-daily-panel', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
193
|
+
FormsModule,
|
|
194
|
+
AXSwitchComponent,
|
|
195
|
+
AXTranslatorPipe,
|
|
196
|
+
AsyncPipe,
|
|
197
|
+
AXSchedulerPickerIntervalSelectorComponent,
|
|
198
|
+
], template: "<div class=\"ax-scheduler-picker-daily-panel\">\n <!-- Interval selector -->\n @if (config().options?.showInterval) {\n <ax-scheduler-picker-interval-selector\n [interval]=\"pattern()?.interval || 1\"\n [config]=\"config()\"\n (intervalChange)=\"onIntervalChange($event)\"\n />\n }\n\n <!-- Weekdays only switch -->\n @if (config().options?.showWeekdaysOnly) {\n <div class=\"ax-scheduler-picker-weekdays-only\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.weekdaysOnly' | translate | async }}\n </label>\n <ax-switch [value]=\"weekdayOnly()\" (valueChange)=\"onWeekdayOnlyChange($event)\" />\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-daily-panel{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-weekday-option{display:flex;align-items:center;justify-content:space-between;padding:.25rem 0}.ax-scheduler-picker-time-selection{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}\n"] }]
|
|
199
|
+
}], ctorParameters: () => [], propDecorators: { pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], patternChange: [{ type: i0.Output, args: ["patternChange"] }] } });
|
|
200
|
+
|
|
201
|
+
class AXSchedulerPickerHourlyPanelComponent {
|
|
202
|
+
constructor() {
|
|
203
|
+
this.pattern = input.required(...(ngDevMode ? [{ debugName: "pattern" }] : []));
|
|
204
|
+
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
205
|
+
this.patternChange = output();
|
|
206
|
+
}
|
|
207
|
+
onIntervalChange(interval) {
|
|
208
|
+
this.patternChange.emit({ interval });
|
|
209
|
+
}
|
|
210
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerHourlyPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
211
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerHourlyPanelComponent, isStandalone: true, selector: "ax-scheduler-picker-hourly-panel", inputs: { pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { patternChange: "patternChange" }, ngImport: i0, template: `
|
|
212
|
+
<div class="ax-scheduler-picker-hourly-panel">
|
|
213
|
+
@if (config().options?.showInterval) {
|
|
214
|
+
<ax-scheduler-picker-interval-selector
|
|
215
|
+
[interval]="pattern()?.interval || 1"
|
|
216
|
+
[config]="config()"
|
|
217
|
+
(intervalChange)="onIntervalChange($event)"
|
|
218
|
+
/>
|
|
219
|
+
}
|
|
220
|
+
</div>
|
|
221
|
+
`, isInline: true, styles: [".ax-scheduler-picker-hourly-panel{display:flex;flex-direction:column;gap:.75rem}\n"], dependencies: [{ kind: "component", type: AXSchedulerPickerIntervalSelectorComponent, selector: "ax-scheduler-picker-interval-selector", inputs: ["interval", "config"], outputs: ["intervalChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
222
|
+
}
|
|
223
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerHourlyPanelComponent, decorators: [{
|
|
224
|
+
type: Component,
|
|
225
|
+
args: [{ selector: 'ax-scheduler-picker-hourly-panel', template: `
|
|
226
|
+
<div class="ax-scheduler-picker-hourly-panel">
|
|
227
|
+
@if (config().options?.showInterval) {
|
|
228
|
+
<ax-scheduler-picker-interval-selector
|
|
229
|
+
[interval]="pattern()?.interval || 1"
|
|
230
|
+
[config]="config()"
|
|
231
|
+
(intervalChange)="onIntervalChange($event)"
|
|
232
|
+
/>
|
|
233
|
+
}
|
|
234
|
+
</div>
|
|
235
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [AXSchedulerPickerIntervalSelectorComponent], styles: [".ax-scheduler-picker-hourly-panel{display:flex;flex-direction:column;gap:.75rem}\n"] }]
|
|
236
|
+
}], propDecorators: { pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], patternChange: [{ type: i0.Output, args: ["patternChange"] }] } });
|
|
237
|
+
|
|
238
|
+
class AXSchedulerPickerDaySelectorComponent {
|
|
239
|
+
constructor() {
|
|
240
|
+
/**
|
|
241
|
+
* Selected day numbers (1-31)
|
|
242
|
+
*/
|
|
243
|
+
this.days = input(...(ngDevMode ? [undefined, { debugName: "days" }] : []));
|
|
244
|
+
/**
|
|
245
|
+
* Emits when day selection changes
|
|
246
|
+
*/
|
|
247
|
+
this.daysChange = output();
|
|
248
|
+
this.dayItems = Array.from({ length: 31 }, (_, i) => ({
|
|
249
|
+
id: i + 1,
|
|
250
|
+
text: String(i + 1),
|
|
251
|
+
}));
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Handle day selection change
|
|
255
|
+
*/
|
|
256
|
+
onDaysChange(event) {
|
|
257
|
+
const selectedDays = Array.isArray(event.value) ? event.value : [event.value];
|
|
258
|
+
this.daysChange.emit(selectedDays.sort((a, b) => a - b));
|
|
259
|
+
}
|
|
260
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerDaySelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
261
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: AXSchedulerPickerDaySelectorComponent, isStandalone: true, selector: "ax-scheduler-picker-day-selector", inputs: { days: { classPropertyName: "days", publicName: "days", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { daysChange: "daysChange" }, ngImport: i0, template: `
|
|
262
|
+
<div class="ax-scheduler-picker-day-selector">
|
|
263
|
+
<label class="ax-scheduler-picker-label">
|
|
264
|
+
{{ '@acorex:schedulerPicker.labels.selectDays' | translate | async }}
|
|
265
|
+
</label>
|
|
266
|
+
<ax-select-box
|
|
267
|
+
[dataSource]="dayItems"
|
|
268
|
+
textField="text"
|
|
269
|
+
valueField="id"
|
|
270
|
+
[multiple]="true"
|
|
271
|
+
[value]="days()"
|
|
272
|
+
(onValueChanged)="onDaysChange($event)"
|
|
273
|
+
/>
|
|
274
|
+
</div>
|
|
275
|
+
`, isInline: true, styles: [".ax-scheduler-picker-day-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}ax-select-box{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
276
|
+
}
|
|
277
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerDaySelectorComponent, decorators: [{
|
|
278
|
+
type: Component,
|
|
279
|
+
args: [{ selector: 'ax-scheduler-picker-day-selector', template: `
|
|
280
|
+
<div class="ax-scheduler-picker-day-selector">
|
|
281
|
+
<label class="ax-scheduler-picker-label">
|
|
282
|
+
{{ '@acorex:schedulerPicker.labels.selectDays' | translate | async }}
|
|
283
|
+
</label>
|
|
284
|
+
<ax-select-box
|
|
285
|
+
[dataSource]="dayItems"
|
|
286
|
+
textField="text"
|
|
287
|
+
valueField="id"
|
|
288
|
+
[multiple]="true"
|
|
289
|
+
[value]="days()"
|
|
290
|
+
(onValueChanged)="onDaysChange($event)"
|
|
291
|
+
/>
|
|
292
|
+
</div>
|
|
293
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [FormsModule, AXSelectBoxComponent, AXTranslatorPipe, AsyncPipe], styles: [".ax-scheduler-picker-day-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}ax-select-box{width:100%}\n"] }]
|
|
294
|
+
}], propDecorators: { days: [{ type: i0.Input, args: [{ isSignal: true, alias: "days", required: false }] }], daysChange: [{ type: i0.Output, args: ["daysChange"] }] } });
|
|
295
|
+
|
|
296
|
+
class AXSchedulerPickerOccurrenceSelectorComponent {
|
|
297
|
+
constructor() {
|
|
298
|
+
/**
|
|
299
|
+
* Current occurrence selection (position + day)
|
|
300
|
+
*/
|
|
301
|
+
this.occurrence = input(...(ngDevMode ? [undefined, { debugName: "occurrence" }] : []));
|
|
302
|
+
/**
|
|
303
|
+
* Emits when occurrence selection changes
|
|
304
|
+
*/
|
|
305
|
+
this.occurrenceChange = output();
|
|
306
|
+
this.selectedPosition = signal(1, ...(ngDevMode ? [{ debugName: "selectedPosition" }] : []));
|
|
307
|
+
this.selectedDay = signal(1, ...(ngDevMode ? [{ debugName: "selectedDay" }] : []));
|
|
308
|
+
this.positions = AX_SCHEDULER_PICKER_OCCURRENCE_POSITIONS.map((pos) => ({
|
|
309
|
+
...pos,
|
|
310
|
+
text: `@acorex:schedulerPicker.positions.${pos.key}`,
|
|
311
|
+
}));
|
|
312
|
+
this.days = AX_SCHEDULER_PICKER_DAYS_OF_WEEK.map((d) => ({
|
|
313
|
+
value: d.id,
|
|
314
|
+
text: `@acorex:schedulerPicker.days.${d.key}`,
|
|
315
|
+
}));
|
|
316
|
+
// Sync input with internal state
|
|
317
|
+
effect(() => {
|
|
318
|
+
const occ = this.occurrence();
|
|
319
|
+
if (occ) {
|
|
320
|
+
this.selectedPosition.set(occ.position);
|
|
321
|
+
this.selectedDay.set(occ.day);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Handle position selection change
|
|
327
|
+
*/
|
|
328
|
+
onPositionChangeEvent(event) {
|
|
329
|
+
this.selectedPosition.set(event.value);
|
|
330
|
+
this.emitChange();
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Handle day selection change
|
|
334
|
+
*/
|
|
335
|
+
onDayChangeEvent(event) {
|
|
336
|
+
const day = event.value;
|
|
337
|
+
this.selectedDay.set(day);
|
|
338
|
+
this.emitChange();
|
|
339
|
+
}
|
|
340
|
+
emitChange() {
|
|
341
|
+
this.occurrenceChange.emit({
|
|
342
|
+
position: this.selectedPosition(),
|
|
343
|
+
day: this.selectedDay(),
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerOccurrenceSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
347
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: AXSchedulerPickerOccurrenceSelectorComponent, isStandalone: true, selector: "ax-scheduler-picker-occurrence-selector", inputs: { occurrence: { classPropertyName: "occurrence", publicName: "occurrence", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { occurrenceChange: "occurrenceChange" }, ngImport: i0, template: `
|
|
348
|
+
<div class="ax-scheduler-picker-occurrence-selector">
|
|
349
|
+
<label class="ax-scheduler-picker-label">
|
|
350
|
+
{{ '@acorex:schedulerPicker.labels.occurrence' | translate | async }}
|
|
351
|
+
</label>
|
|
352
|
+
|
|
353
|
+
<div class="ax-scheduler-picker-row">
|
|
354
|
+
<ax-select-box
|
|
355
|
+
[value]="selectedPosition()"
|
|
356
|
+
[dataSource]="positions"
|
|
357
|
+
textField="text"
|
|
358
|
+
valueField="value"
|
|
359
|
+
(onValueChanged)="onPositionChangeEvent($event)"
|
|
360
|
+
/>
|
|
361
|
+
<ax-select-box
|
|
362
|
+
[value]="selectedDay()"
|
|
363
|
+
[dataSource]="days"
|
|
364
|
+
textField="text"
|
|
365
|
+
valueField="value"
|
|
366
|
+
(onValueChanged)="onDayChangeEvent($event)"
|
|
367
|
+
/>
|
|
368
|
+
</div>
|
|
369
|
+
</div>
|
|
370
|
+
`, isInline: true, styles: [".ax-scheduler-picker-occurrence-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-row{display:flex;gap:.5rem}.ax-scheduler-picker-row>*{flex:1}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
371
|
+
}
|
|
372
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerOccurrenceSelectorComponent, decorators: [{
|
|
373
|
+
type: Component,
|
|
374
|
+
args: [{ selector: 'ax-scheduler-picker-occurrence-selector', template: `
|
|
375
|
+
<div class="ax-scheduler-picker-occurrence-selector">
|
|
376
|
+
<label class="ax-scheduler-picker-label">
|
|
377
|
+
{{ '@acorex:schedulerPicker.labels.occurrence' | translate | async }}
|
|
378
|
+
</label>
|
|
379
|
+
|
|
380
|
+
<div class="ax-scheduler-picker-row">
|
|
381
|
+
<ax-select-box
|
|
382
|
+
[value]="selectedPosition()"
|
|
383
|
+
[dataSource]="positions"
|
|
384
|
+
textField="text"
|
|
385
|
+
valueField="value"
|
|
386
|
+
(onValueChanged)="onPositionChangeEvent($event)"
|
|
387
|
+
/>
|
|
388
|
+
<ax-select-box
|
|
389
|
+
[value]="selectedDay()"
|
|
390
|
+
[dataSource]="days"
|
|
391
|
+
textField="text"
|
|
392
|
+
valueField="value"
|
|
393
|
+
(onValueChanged)="onDayChangeEvent($event)"
|
|
394
|
+
/>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [FormsModule, AXSelectBoxComponent, AXTranslatorPipe, AsyncPipe], styles: [".ax-scheduler-picker-occurrence-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-row{display:flex;gap:.5rem}.ax-scheduler-picker-row>*{flex:1}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}\n"] }]
|
|
398
|
+
}], ctorParameters: () => [], propDecorators: { occurrence: [{ type: i0.Input, args: [{ isSignal: true, alias: "occurrence", required: false }] }], occurrenceChange: [{ type: i0.Output, args: ["occurrenceChange"] }] } });
|
|
399
|
+
|
|
400
|
+
class AXSchedulerPickerMonthlyPanelComponent {
|
|
401
|
+
constructor() {
|
|
402
|
+
this.pattern = input.required(...(ngDevMode ? [{ debugName: "pattern" }] : []));
|
|
403
|
+
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
404
|
+
this.patternChange = output();
|
|
405
|
+
this.selectedDays = signal([], ...(ngDevMode ? [{ debugName: "selectedDays" }] : []));
|
|
406
|
+
this.occurrence = signal(null, ...(ngDevMode ? [{ debugName: "occurrence" }] : []));
|
|
407
|
+
// Initialize state from pattern
|
|
408
|
+
effect(() => {
|
|
409
|
+
const pattern = this.pattern();
|
|
410
|
+
if (pattern?.recurrence) {
|
|
411
|
+
if (pattern.recurrence.byDay) {
|
|
412
|
+
this.selectedDays.set(pattern.recurrence.byDay);
|
|
413
|
+
}
|
|
414
|
+
if (pattern.recurrence.byOccurrence && pattern.recurrence.byOccurrence.length > 0) {
|
|
415
|
+
const occ = pattern.recurrence.byOccurrence[0];
|
|
416
|
+
this.occurrence.set({ position: occ.position, day: occ.dayOfWeek });
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
onIntervalChange(interval) {
|
|
422
|
+
this.patternChange.emit({ interval });
|
|
423
|
+
}
|
|
424
|
+
onDaysChange(days) {
|
|
425
|
+
this.selectedDays.set(days);
|
|
426
|
+
this.patternChange.emit({
|
|
427
|
+
recurrence: {
|
|
428
|
+
...this.pattern()?.recurrence,
|
|
429
|
+
byDay: days,
|
|
430
|
+
byOccurrence: undefined, // Clear occurrence when using specific days
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
onOccurrenceChange(occurrence) {
|
|
435
|
+
this.occurrence.set(occurrence);
|
|
436
|
+
this.patternChange.emit({
|
|
437
|
+
recurrence: {
|
|
438
|
+
...this.pattern()?.recurrence,
|
|
439
|
+
byOccurrence: [{ position: occurrence.position, dayOfWeek: occurrence.day }],
|
|
440
|
+
byDay: undefined, // Clear days when using occurrence
|
|
441
|
+
},
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerMonthlyPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
445
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerMonthlyPanelComponent, isStandalone: true, selector: "ax-scheduler-picker-monthly-panel", inputs: { pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { patternChange: "patternChange" }, ngImport: i0, template: "<div class=\"ax-scheduler-picker-monthly-panel\">\n <!-- Interval selector -->\n @if (config().options?.showInterval) {\n <ax-scheduler-picker-interval-selector\n [interval]=\"pattern()?.interval || 1\"\n [config]=\"config()\"\n (intervalChange)=\"onIntervalChange($event)\"\n />\n }\n\n <!-- Specific Days Mode: Calendar day picker -->\n @if (config().options?.recurrenceMode === 'specificDays') {\n <ax-scheduler-picker-day-selector\n [days]=\"selectedDays()\"\n (daysChange)=\"onDaysChange($event)\"\n />\n }\n\n <!-- Occurrence Mode: Position + Weekday selectors -->\n @if (config().options?.recurrenceMode === 'occurrence') {\n <ax-scheduler-picker-occurrence-selector\n [occurrence]=\"occurrence()\"\n (occurrenceChange)=\"onOccurrenceChange($event)\"\n />\n }\n</div>\n", styles: [".ax-scheduler-picker-monthly-panel{display:flex;flex-direction:column;gap:.5rem}\n"], dependencies: [{ kind: "component", type: AXSchedulerPickerIntervalSelectorComponent, selector: "ax-scheduler-picker-interval-selector", inputs: ["interval", "config"], outputs: ["intervalChange"] }, { kind: "component", type: AXSchedulerPickerDaySelectorComponent, selector: "ax-scheduler-picker-day-selector", inputs: ["days"], outputs: ["daysChange"] }, { kind: "component", type: AXSchedulerPickerOccurrenceSelectorComponent, selector: "ax-scheduler-picker-occurrence-selector", inputs: ["occurrence"], outputs: ["occurrenceChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
446
|
+
}
|
|
447
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerMonthlyPanelComponent, decorators: [{
|
|
448
|
+
type: Component,
|
|
449
|
+
args: [{ selector: 'ax-scheduler-picker-monthly-panel', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
450
|
+
AXSchedulerPickerIntervalSelectorComponent,
|
|
451
|
+
AXSchedulerPickerDaySelectorComponent,
|
|
452
|
+
AXSchedulerPickerOccurrenceSelectorComponent,
|
|
453
|
+
], template: "<div class=\"ax-scheduler-picker-monthly-panel\">\n <!-- Interval selector -->\n @if (config().options?.showInterval) {\n <ax-scheduler-picker-interval-selector\n [interval]=\"pattern()?.interval || 1\"\n [config]=\"config()\"\n (intervalChange)=\"onIntervalChange($event)\"\n />\n }\n\n <!-- Specific Days Mode: Calendar day picker -->\n @if (config().options?.recurrenceMode === 'specificDays') {\n <ax-scheduler-picker-day-selector\n [days]=\"selectedDays()\"\n (daysChange)=\"onDaysChange($event)\"\n />\n }\n\n <!-- Occurrence Mode: Position + Weekday selectors -->\n @if (config().options?.recurrenceMode === 'occurrence') {\n <ax-scheduler-picker-occurrence-selector\n [occurrence]=\"occurrence()\"\n (occurrenceChange)=\"onOccurrenceChange($event)\"\n />\n }\n</div>\n", styles: [".ax-scheduler-picker-monthly-panel{display:flex;flex-direction:column;gap:.5rem}\n"] }]
|
|
454
|
+
}], ctorParameters: () => [], propDecorators: { pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], patternChange: [{ type: i0.Output, args: ["patternChange"] }] } });
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Helper function to reorder days based on first day of week
|
|
458
|
+
*/
|
|
459
|
+
function reorderDaysByFirstDay(firstDayOfWeek = AX_SCHEDULER_PICKER_DEFAULT_FIRST_DAY_OF_WEEK) {
|
|
460
|
+
return [...AX_SCHEDULER_PICKER_DAYS_OF_WEEK.slice(firstDayOfWeek), ...AX_SCHEDULER_PICKER_DAYS_OF_WEEK.slice(0, firstDayOfWeek)];
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Get RRule day key by day index
|
|
464
|
+
*/
|
|
465
|
+
function getRRuleDayKey(dayIndex) {
|
|
466
|
+
return AX_SCHEDULER_PICKER_RRULE_DAY_KEYS[dayIndex] || 'MO';
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Get day translation key by index
|
|
470
|
+
*/
|
|
471
|
+
function getDayTranslationKey(dayIndex) {
|
|
472
|
+
return AX_SCHEDULER_PICKER_DAY_TRANSLATION_KEYS[dayIndex] || 'monday';
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Get month translation key by index
|
|
476
|
+
*/
|
|
477
|
+
function getMonthTranslationKey(monthIndex) {
|
|
478
|
+
return AX_SCHEDULER_PICKER_MONTH_TRANSLATION_KEYS[monthIndex] || 'january';
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Normalize date to midnight for consistent comparison
|
|
482
|
+
*/
|
|
483
|
+
function normalizeDate(date) {
|
|
484
|
+
const normalized = new Date(date);
|
|
485
|
+
normalized.setHours(0, 0, 0, 0);
|
|
486
|
+
return normalized;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Check if two dates are the same day (ignoring time)
|
|
490
|
+
*/
|
|
491
|
+
function isSameDate(date1, date2) {
|
|
492
|
+
return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Check if date exists in array (day comparison only)
|
|
496
|
+
*/
|
|
497
|
+
function dateExistsInArray(date, dates) {
|
|
498
|
+
const normalized = normalizeDate(date);
|
|
499
|
+
return dates.some((d) => normalizeDate(d).getTime() === normalized.getTime());
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Weekly recurrence panel
|
|
504
|
+
*/
|
|
505
|
+
class AXSchedulerPickerWeeklyPanelComponent {
|
|
506
|
+
constructor() {
|
|
507
|
+
this.pattern = input.required(...(ngDevMode ? [{ debugName: "pattern" }] : []));
|
|
508
|
+
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
509
|
+
this.patternChange = output();
|
|
510
|
+
this.selectedDays = signal([], ...(ngDevMode ? [{ debugName: "selectedDays" }] : []));
|
|
511
|
+
this.dayItems = computed(() => {
|
|
512
|
+
const firstDay = this.config().firstDayOfWeek || 0;
|
|
513
|
+
const days = reorderDaysByFirstDay(firstDay);
|
|
514
|
+
return days.map((day) => ({
|
|
515
|
+
...day,
|
|
516
|
+
text: `@acorex:schedulerPicker.days.${day.key}`,
|
|
517
|
+
}));
|
|
518
|
+
}, ...(ngDevMode ? [{ debugName: "dayItems" }] : []));
|
|
519
|
+
// Initialize selectedDays from pattern
|
|
520
|
+
effect(() => {
|
|
521
|
+
const pattern = this.pattern();
|
|
522
|
+
if (pattern?.recurrence?.byDay) {
|
|
523
|
+
this.selectedDays.set(pattern.recurrence.byDay);
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
onIntervalChange(interval) {
|
|
528
|
+
this.patternChange.emit({ interval });
|
|
529
|
+
}
|
|
530
|
+
onDaysChange(event) {
|
|
531
|
+
const days = event.value;
|
|
532
|
+
this.selectedDays.set(days);
|
|
533
|
+
this.patternChange.emit({
|
|
534
|
+
recurrence: {
|
|
535
|
+
...this.pattern()?.recurrence,
|
|
536
|
+
byDay: days,
|
|
537
|
+
},
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerWeeklyPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
541
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerWeeklyPanelComponent, isStandalone: true, selector: "ax-scheduler-picker-weekly-panel", inputs: { pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { patternChange: "patternChange" }, ngImport: i0, template: "<div class=\"ax-scheduler-picker-weekly-panel\">\n <!-- Interval selector -->\n @if (config().options?.showInterval) {\n <ax-scheduler-picker-interval-selector\n [interval]=\"pattern()?.interval || 1\"\n [config]=\"config()\"\n (intervalChange)=\"onIntervalChange($event)\"\n />\n }\n\n <!-- Day selection -->\n @if (config().options?.showWeekdaySelection) {\n <div class=\"ax-scheduler-picker-day-selection\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.onDays' | translate | async }}\n </label>\n <ax-selection-list\n [items]=\"dayItems()\"\n [multiple]=\"true\"\n [showControl]=\"true\"\n [look]=\"'solid'\"\n [direction]=\"'horizontal'\"\n [value]=\"selectedDays()\"\n (onValueChanged)=\"onDaysChange($event)\"\n />\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-weekly-panel{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-day-selection,.ax-scheduler-picker-time-selection{display:flex;flex-direction:column;gap:.375rem}ax-selection-list{width:100%}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "component", type: i1.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: AXSchedulerPickerIntervalSelectorComponent, selector: "ax-scheduler-picker-interval-selector", inputs: ["interval", "config"], outputs: ["intervalChange"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
542
|
+
}
|
|
543
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerWeeklyPanelComponent, decorators: [{
|
|
544
|
+
type: Component,
|
|
545
|
+
args: [{ selector: 'ax-scheduler-picker-weekly-panel', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
546
|
+
FormsModule,
|
|
547
|
+
AXSelectionListModule,
|
|
548
|
+
AXTranslatorPipe,
|
|
549
|
+
AsyncPipe,
|
|
550
|
+
AXSchedulerPickerIntervalSelectorComponent,
|
|
551
|
+
], template: "<div class=\"ax-scheduler-picker-weekly-panel\">\n <!-- Interval selector -->\n @if (config().options?.showInterval) {\n <ax-scheduler-picker-interval-selector\n [interval]=\"pattern()?.interval || 1\"\n [config]=\"config()\"\n (intervalChange)=\"onIntervalChange($event)\"\n />\n }\n\n <!-- Day selection -->\n @if (config().options?.showWeekdaySelection) {\n <div class=\"ax-scheduler-picker-day-selection\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.onDays' | translate | async }}\n </label>\n <ax-selection-list\n [items]=\"dayItems()\"\n [multiple]=\"true\"\n [showControl]=\"true\"\n [look]=\"'solid'\"\n [direction]=\"'horizontal'\"\n [value]=\"selectedDays()\"\n (onValueChanged)=\"onDaysChange($event)\"\n />\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-weekly-panel{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-day-selection,.ax-scheduler-picker-time-selection{display:flex;flex-direction:column;gap:.375rem}ax-selection-list{width:100%}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}\n"] }]
|
|
552
|
+
}], ctorParameters: () => [], propDecorators: { pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], patternChange: [{ type: i0.Output, args: ["patternChange"] }] } });
|
|
553
|
+
|
|
554
|
+
class AXSchedulerPickerMonthSelectorComponent {
|
|
555
|
+
constructor() {
|
|
556
|
+
/**
|
|
557
|
+
* Selected month indices (0-11)
|
|
558
|
+
*/
|
|
559
|
+
this.months = input(...(ngDevMode ? [undefined, { debugName: "months" }] : []));
|
|
560
|
+
/**
|
|
561
|
+
* Emits when month selection changes
|
|
562
|
+
*/
|
|
563
|
+
this.monthsChange = output();
|
|
564
|
+
this.monthItems = AX_SCHEDULER_PICKER_MONTHS.map((month) => ({
|
|
565
|
+
...month,
|
|
566
|
+
text: `@acorex:schedulerPicker.months.${month.key}`,
|
|
567
|
+
}));
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Handle month selection change
|
|
571
|
+
*/
|
|
572
|
+
onMonthsChange(event) {
|
|
573
|
+
const selectedMonths = Array.isArray(event.value) ? event.value : [event.value];
|
|
574
|
+
this.monthsChange.emit(selectedMonths.sort((a, b) => a - b));
|
|
575
|
+
}
|
|
576
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerMonthSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
577
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: AXSchedulerPickerMonthSelectorComponent, isStandalone: true, selector: "ax-scheduler-picker-month-selector", inputs: { months: { classPropertyName: "months", publicName: "months", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { monthsChange: "monthsChange" }, ngImport: i0, template: `
|
|
578
|
+
<div class="ax-scheduler-picker-month-selector">
|
|
579
|
+
<label class="ax-scheduler-picker-label">
|
|
580
|
+
{{ '@acorex:schedulerPicker.labels.selectMonths' | translate | async }}
|
|
581
|
+
</label>
|
|
582
|
+
<ax-select-box
|
|
583
|
+
[dataSource]="monthItems"
|
|
584
|
+
textField="text"
|
|
585
|
+
valueField="id"
|
|
586
|
+
[multiple]="true"
|
|
587
|
+
[value]="months()"
|
|
588
|
+
(onValueChanged)="onMonthsChange($event)"
|
|
589
|
+
/>
|
|
590
|
+
</div>
|
|
591
|
+
`, isInline: true, styles: [".ax-scheduler-picker-month-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}ax-select-box{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
592
|
+
}
|
|
593
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerMonthSelectorComponent, decorators: [{
|
|
594
|
+
type: Component,
|
|
595
|
+
args: [{ selector: 'ax-scheduler-picker-month-selector', template: `
|
|
596
|
+
<div class="ax-scheduler-picker-month-selector">
|
|
597
|
+
<label class="ax-scheduler-picker-label">
|
|
598
|
+
{{ '@acorex:schedulerPicker.labels.selectMonths' | translate | async }}
|
|
599
|
+
</label>
|
|
600
|
+
<ax-select-box
|
|
601
|
+
[dataSource]="monthItems"
|
|
602
|
+
textField="text"
|
|
603
|
+
valueField="id"
|
|
604
|
+
[multiple]="true"
|
|
605
|
+
[value]="months()"
|
|
606
|
+
(onValueChanged)="onMonthsChange($event)"
|
|
607
|
+
/>
|
|
608
|
+
</div>
|
|
609
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [FormsModule, AXSelectBoxComponent, AXTranslatorPipe, AsyncPipe], styles: [".ax-scheduler-picker-month-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}ax-select-box{width:100%}\n"] }]
|
|
610
|
+
}], propDecorators: { months: [{ type: i0.Input, args: [{ isSignal: true, alias: "months", required: false }] }], monthsChange: [{ type: i0.Output, args: ["monthsChange"] }] } });
|
|
611
|
+
|
|
612
|
+
class AXSchedulerPickerYearlyPanelComponent {
|
|
613
|
+
constructor() {
|
|
614
|
+
this.pattern = input.required(...(ngDevMode ? [{ debugName: "pattern" }] : []));
|
|
615
|
+
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
616
|
+
this.patternChange = output();
|
|
617
|
+
this.selectedMonths = signal([], ...(ngDevMode ? [{ debugName: "selectedMonths" }] : []));
|
|
618
|
+
this.selectedDays = signal([], ...(ngDevMode ? [{ debugName: "selectedDays" }] : []));
|
|
619
|
+
this.occurrence = signal(null, ...(ngDevMode ? [{ debugName: "occurrence" }] : []));
|
|
620
|
+
// Initialize state from pattern
|
|
621
|
+
effect(() => {
|
|
622
|
+
const pattern = this.pattern();
|
|
623
|
+
if (pattern?.recurrence) {
|
|
624
|
+
if (pattern.recurrence.byMonth) {
|
|
625
|
+
this.selectedMonths.set(pattern.recurrence.byMonth);
|
|
626
|
+
}
|
|
627
|
+
if (pattern.recurrence.byDay) {
|
|
628
|
+
this.selectedDays.set(pattern.recurrence.byDay);
|
|
629
|
+
}
|
|
630
|
+
if (pattern.recurrence.byOccurrence && pattern.recurrence.byOccurrence.length > 0) {
|
|
631
|
+
const occ = pattern.recurrence.byOccurrence[0];
|
|
632
|
+
this.occurrence.set({ position: occ.position, day: occ.dayOfWeek });
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
onIntervalChange(interval) {
|
|
638
|
+
this.patternChange.emit({ interval });
|
|
639
|
+
}
|
|
640
|
+
onMonthsChange(months) {
|
|
641
|
+
this.selectedMonths.set(months);
|
|
642
|
+
this.patternChange.emit({
|
|
643
|
+
recurrence: {
|
|
644
|
+
...this.pattern()?.recurrence,
|
|
645
|
+
byMonth: months,
|
|
646
|
+
},
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
onDaysChange(days) {
|
|
650
|
+
this.selectedDays.set(days);
|
|
651
|
+
this.patternChange.emit({
|
|
652
|
+
recurrence: {
|
|
653
|
+
...this.pattern()?.recurrence,
|
|
654
|
+
byDay: days,
|
|
655
|
+
byOccurrence: undefined, // Clear occurrence when using specific date
|
|
656
|
+
},
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
onOccurrenceChange(occurrence) {
|
|
660
|
+
this.occurrence.set(occurrence);
|
|
661
|
+
this.patternChange.emit({
|
|
662
|
+
recurrence: {
|
|
663
|
+
...this.pattern()?.recurrence,
|
|
664
|
+
byOccurrence: [{ position: occurrence.position, dayOfWeek: occurrence.day }],
|
|
665
|
+
byDay: undefined, // Clear days when using occurrence
|
|
666
|
+
},
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerYearlyPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
670
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerYearlyPanelComponent, isStandalone: true, selector: "ax-scheduler-picker-yearly-panel", inputs: { pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { patternChange: "patternChange" }, ngImport: i0, template: "<div class=\"ax-scheduler-picker-yearly-panel\">\n <!-- Interval selector -->\n @if (config().options?.showInterval) {\n <ax-scheduler-picker-interval-selector\n [interval]=\"pattern()?.interval || 1\"\n [config]=\"config()\"\n (intervalChange)=\"onIntervalChange($event)\"\n />\n }\n\n <!-- Month selector (independent of recurrence mode) -->\n @if (config().options?.showMonthSelection !== false) {\n <ax-scheduler-picker-month-selector\n [months]=\"selectedMonths()\"\n (monthsChange)=\"onMonthsChange($event)\"\n />\n }\n\n <!-- Specific Date Mode: Day picker -->\n @if (config().options?.recurrenceMode === 'specificDate') {\n <ax-scheduler-picker-day-selector\n [days]=\"selectedDays()\"\n (daysChange)=\"onDaysChange($event)\"\n />\n }\n\n <!-- Occurrence Mode: Month + Position + Weekday selectors -->\n @if (config().options?.recurrenceMode === 'occurrence') {\n @if (config().options?.showMonthSelection !== false) {\n <ax-scheduler-picker-month-selector\n [months]=\"selectedMonths()\"\n (monthsChange)=\"onMonthsChange($event)\"\n />\n }\n <ax-scheduler-picker-occurrence-selector\n [occurrence]=\"occurrence()\"\n (occurrenceChange)=\"onOccurrenceChange($event)\"\n />\n }\n</div>\n", styles: [".ax-scheduler-picker-yearly-panel{display:flex;flex-direction:column;gap:.5rem}\n"], dependencies: [{ kind: "component", type: AXSchedulerPickerIntervalSelectorComponent, selector: "ax-scheduler-picker-interval-selector", inputs: ["interval", "config"], outputs: ["intervalChange"] }, { kind: "component", type: AXSchedulerPickerMonthSelectorComponent, selector: "ax-scheduler-picker-month-selector", inputs: ["months"], outputs: ["monthsChange"] }, { kind: "component", type: AXSchedulerPickerDaySelectorComponent, selector: "ax-scheduler-picker-day-selector", inputs: ["days"], outputs: ["daysChange"] }, { kind: "component", type: AXSchedulerPickerOccurrenceSelectorComponent, selector: "ax-scheduler-picker-occurrence-selector", inputs: ["occurrence"], outputs: ["occurrenceChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
671
|
+
}
|
|
672
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerYearlyPanelComponent, decorators: [{
|
|
673
|
+
type: Component,
|
|
674
|
+
args: [{ selector: 'ax-scheduler-picker-yearly-panel', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
675
|
+
AXSchedulerPickerIntervalSelectorComponent,
|
|
676
|
+
AXSchedulerPickerMonthSelectorComponent,
|
|
677
|
+
AXSchedulerPickerDaySelectorComponent,
|
|
678
|
+
AXSchedulerPickerOccurrenceSelectorComponent,
|
|
679
|
+
], template: "<div class=\"ax-scheduler-picker-yearly-panel\">\n <!-- Interval selector -->\n @if (config().options?.showInterval) {\n <ax-scheduler-picker-interval-selector\n [interval]=\"pattern()?.interval || 1\"\n [config]=\"config()\"\n (intervalChange)=\"onIntervalChange($event)\"\n />\n }\n\n <!-- Month selector (independent of recurrence mode) -->\n @if (config().options?.showMonthSelection !== false) {\n <ax-scheduler-picker-month-selector\n [months]=\"selectedMonths()\"\n (monthsChange)=\"onMonthsChange($event)\"\n />\n }\n\n <!-- Specific Date Mode: Day picker -->\n @if (config().options?.recurrenceMode === 'specificDate') {\n <ax-scheduler-picker-day-selector\n [days]=\"selectedDays()\"\n (daysChange)=\"onDaysChange($event)\"\n />\n }\n\n <!-- Occurrence Mode: Month + Position + Weekday selectors -->\n @if (config().options?.recurrenceMode === 'occurrence') {\n @if (config().options?.showMonthSelection !== false) {\n <ax-scheduler-picker-month-selector\n [months]=\"selectedMonths()\"\n (monthsChange)=\"onMonthsChange($event)\"\n />\n }\n <ax-scheduler-picker-occurrence-selector\n [occurrence]=\"occurrence()\"\n (occurrenceChange)=\"onOccurrenceChange($event)\"\n />\n }\n</div>\n", styles: [".ax-scheduler-picker-yearly-panel{display:flex;flex-direction:column;gap:.5rem}\n"] }]
|
|
680
|
+
}], ctorParameters: () => [], propDecorators: { pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], patternChange: [{ type: i0.Output, args: ["patternChange"] }] } });
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Hourly mode default configuration
|
|
684
|
+
*/
|
|
685
|
+
const AXSchedulerPickerHourlyDefaultConfig = {
|
|
686
|
+
mode: 'hourly',
|
|
687
|
+
showEndConditions: true,
|
|
688
|
+
showExclusions: false,
|
|
689
|
+
showInclusions: false,
|
|
690
|
+
defaultInterval: 1,
|
|
691
|
+
minInterval: 1,
|
|
692
|
+
maxInterval: 23,
|
|
693
|
+
firstDayOfWeek: 0,
|
|
694
|
+
options: {
|
|
695
|
+
showInterval: true,
|
|
696
|
+
},
|
|
697
|
+
};
|
|
698
|
+
/**
|
|
699
|
+
* Daily mode default configuration
|
|
700
|
+
*/
|
|
701
|
+
const AXSchedulerPickerDailyDefaultConfig = {
|
|
702
|
+
mode: 'daily',
|
|
703
|
+
showEndConditions: true,
|
|
704
|
+
showExclusions: false,
|
|
705
|
+
showInclusions: false,
|
|
706
|
+
defaultInterval: 1,
|
|
707
|
+
minInterval: 1,
|
|
708
|
+
maxInterval: 365,
|
|
709
|
+
firstDayOfWeek: 0,
|
|
710
|
+
options: {
|
|
711
|
+
showInterval: true,
|
|
712
|
+
showWeekdaysOnly: true,
|
|
713
|
+
},
|
|
714
|
+
};
|
|
715
|
+
/**
|
|
716
|
+
* Weekly mode default configuration
|
|
717
|
+
*/
|
|
718
|
+
const AXSchedulerPickerWeeklyDefaultConfig = {
|
|
719
|
+
mode: 'weekly',
|
|
720
|
+
showEndConditions: true,
|
|
721
|
+
showExclusions: false,
|
|
722
|
+
showInclusions: false,
|
|
723
|
+
defaultInterval: 1,
|
|
724
|
+
minInterval: 1,
|
|
725
|
+
maxInterval: 52,
|
|
726
|
+
firstDayOfWeek: 0,
|
|
727
|
+
options: {
|
|
728
|
+
showInterval: true,
|
|
729
|
+
showWeekdaySelection: true,
|
|
730
|
+
},
|
|
731
|
+
};
|
|
732
|
+
/**
|
|
733
|
+
* Monthly mode default configuration
|
|
734
|
+
*/
|
|
735
|
+
const AXSchedulerPickerMonthlyDefaultConfig = {
|
|
736
|
+
mode: 'monthly',
|
|
737
|
+
showEndConditions: true,
|
|
738
|
+
showExclusions: false,
|
|
739
|
+
showInclusions: false,
|
|
740
|
+
defaultInterval: 1,
|
|
741
|
+
minInterval: 1,
|
|
742
|
+
maxInterval: 12,
|
|
743
|
+
firstDayOfWeek: 0,
|
|
744
|
+
options: {
|
|
745
|
+
showInterval: true,
|
|
746
|
+
recurrenceMode: 'specificDays',
|
|
747
|
+
},
|
|
748
|
+
};
|
|
749
|
+
/**
|
|
750
|
+
* Yearly mode default configuration
|
|
751
|
+
*/
|
|
752
|
+
const AXSchedulerPickerYearlyDefaultConfig = {
|
|
753
|
+
mode: 'yearly',
|
|
754
|
+
showEndConditions: true,
|
|
755
|
+
showExclusions: false,
|
|
756
|
+
showInclusions: false,
|
|
757
|
+
defaultInterval: 1,
|
|
758
|
+
minInterval: 1,
|
|
759
|
+
maxInterval: 10,
|
|
760
|
+
firstDayOfWeek: 0,
|
|
761
|
+
options: {
|
|
762
|
+
showInterval: true,
|
|
763
|
+
recurrenceMode: 'specificDate',
|
|
764
|
+
},
|
|
765
|
+
};
|
|
766
|
+
/**
|
|
767
|
+
* Injection tokens for each mode configuration
|
|
768
|
+
*/
|
|
769
|
+
const AX_SCHEDULER_PICKER_HOURLY_CONFIG = new InjectionToken('AX_SCHEDULER_PICKER_HOURLY_CONFIG', {
|
|
770
|
+
providedIn: 'root',
|
|
771
|
+
factory: () => AXSchedulerPickerHourlyDefaultConfig,
|
|
772
|
+
});
|
|
773
|
+
const AX_SCHEDULER_PICKER_DAILY_CONFIG = new InjectionToken('AX_SCHEDULER_PICKER_DAILY_CONFIG', {
|
|
774
|
+
providedIn: 'root',
|
|
775
|
+
factory: () => AXSchedulerPickerDailyDefaultConfig,
|
|
776
|
+
});
|
|
777
|
+
const AX_SCHEDULER_PICKER_WEEKLY_CONFIG = new InjectionToken('AX_SCHEDULER_PICKER_WEEKLY_CONFIG', {
|
|
778
|
+
providedIn: 'root',
|
|
779
|
+
factory: () => AXSchedulerPickerWeeklyDefaultConfig,
|
|
780
|
+
});
|
|
781
|
+
const AX_SCHEDULER_PICKER_MONTHLY_CONFIG = new InjectionToken('AX_SCHEDULER_PICKER_MONTHLY_CONFIG', {
|
|
782
|
+
providedIn: 'root',
|
|
783
|
+
factory: () => AXSchedulerPickerMonthlyDefaultConfig,
|
|
784
|
+
});
|
|
785
|
+
const AX_SCHEDULER_PICKER_YEARLY_CONFIG = new InjectionToken('AX_SCHEDULER_PICKER_YEARLY_CONFIG', {
|
|
786
|
+
providedIn: 'root',
|
|
787
|
+
factory: () => AXSchedulerPickerYearlyDefaultConfig,
|
|
788
|
+
});
|
|
789
|
+
/**
|
|
790
|
+
* Helper function to get default config by mode
|
|
791
|
+
*/
|
|
792
|
+
function getDefaultSchedulerPickerConfig(mode) {
|
|
793
|
+
switch (mode) {
|
|
794
|
+
case 'hourly':
|
|
795
|
+
return AXSchedulerPickerHourlyDefaultConfig;
|
|
796
|
+
case 'daily':
|
|
797
|
+
return AXSchedulerPickerDailyDefaultConfig;
|
|
798
|
+
case 'weekly':
|
|
799
|
+
return AXSchedulerPickerWeeklyDefaultConfig;
|
|
800
|
+
case 'monthly':
|
|
801
|
+
return AXSchedulerPickerMonthlyDefaultConfig;
|
|
802
|
+
case 'yearly':
|
|
803
|
+
return AXSchedulerPickerYearlyDefaultConfig;
|
|
804
|
+
default:
|
|
805
|
+
throw new Error(`Unknown mode: ${mode}`);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Service for scheduler picker utilities
|
|
811
|
+
* Handles conversions, calculations, and validation
|
|
812
|
+
*/
|
|
813
|
+
class AXSchedulerPickerService {
|
|
814
|
+
constructor() {
|
|
815
|
+
this.translationService = inject(AXTranslationService);
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Calculate next N occurrences from pattern
|
|
819
|
+
* Uses lazy-loaded rrule library for complex calculations
|
|
820
|
+
*/
|
|
821
|
+
async calculateOccurrences(pattern, count, startFrom) {
|
|
822
|
+
const { RRule } = await import('rrule');
|
|
823
|
+
const rruleObj = this.toRRuleObject(pattern, RRule);
|
|
824
|
+
if (!rruleObj) {
|
|
825
|
+
return [];
|
|
826
|
+
}
|
|
827
|
+
const start = startFrom || new Date();
|
|
828
|
+
return rruleObj.after(start, true) ? rruleObj.all((date, i) => i < count) : [];
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Convert pattern to cron expression
|
|
832
|
+
* Uses lazy-loaded cron-parser library
|
|
833
|
+
*/
|
|
834
|
+
async toCronExpression(pattern) {
|
|
835
|
+
// Lazy load cron-parser if needed for validation
|
|
836
|
+
const { parseExpression } = await import('cron-parser');
|
|
837
|
+
// Build cron expression based on pattern
|
|
838
|
+
const parts = ['*', '*', '*', '*', '*'];
|
|
839
|
+
switch (pattern.mode) {
|
|
840
|
+
case 'hourly':
|
|
841
|
+
if (pattern.recurrence.byMinute) {
|
|
842
|
+
parts[0] = pattern.recurrence.byMinute.join(',');
|
|
843
|
+
}
|
|
844
|
+
if (pattern.recurrence.byHour) {
|
|
845
|
+
parts[1] = pattern.recurrence.byHour.join(',');
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
parts[1] = `*/${pattern.interval}`;
|
|
849
|
+
}
|
|
850
|
+
break;
|
|
851
|
+
case 'daily':
|
|
852
|
+
parts[2] = `*/${pattern.interval}`;
|
|
853
|
+
break;
|
|
854
|
+
case 'weekly':
|
|
855
|
+
if (pattern.recurrence.byDay) {
|
|
856
|
+
parts[4] = pattern.recurrence.byDay.join(',');
|
|
857
|
+
}
|
|
858
|
+
break;
|
|
859
|
+
case 'monthly':
|
|
860
|
+
if (pattern.recurrence.byDay) {
|
|
861
|
+
parts[2] = pattern.recurrence.byDay.join(',');
|
|
862
|
+
}
|
|
863
|
+
break;
|
|
864
|
+
case 'yearly':
|
|
865
|
+
if (pattern.recurrence.byDay) {
|
|
866
|
+
parts[2] = pattern.recurrence.byDay.join(',');
|
|
867
|
+
}
|
|
868
|
+
if (pattern.recurrence.byMonth) {
|
|
869
|
+
parts[3] = pattern.recurrence.byMonth.join(',');
|
|
870
|
+
}
|
|
871
|
+
break;
|
|
872
|
+
}
|
|
873
|
+
const cronExpr = parts.join(' ');
|
|
874
|
+
// Validate the cron expression
|
|
875
|
+
try {
|
|
876
|
+
parseExpression(cronExpr);
|
|
877
|
+
return cronExpr;
|
|
878
|
+
}
|
|
879
|
+
catch {
|
|
880
|
+
// Return default cron if generation fails
|
|
881
|
+
return '* * * * *';
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Convert cron expression to pattern
|
|
886
|
+
* Parses standard cron format: minute hour day month weekday
|
|
887
|
+
*/
|
|
888
|
+
async fromCronExpression(cron) {
|
|
889
|
+
try {
|
|
890
|
+
const { parseExpression } = await import('cron-parser');
|
|
891
|
+
const parsed = parseExpression(cron);
|
|
892
|
+
const fields = parsed.fields;
|
|
893
|
+
// Analyze cron fields to determine mode
|
|
894
|
+
const minutePattern = this.analyzeCronField(fields.minute);
|
|
895
|
+
const hourPattern = this.analyzeCronField(fields.hour);
|
|
896
|
+
const dayPattern = this.analyzeCronField(fields.dayOfMonth);
|
|
897
|
+
const monthPattern = this.analyzeCronField(fields.month);
|
|
898
|
+
const weekdayPattern = this.analyzeCronField(fields.dayOfWeek);
|
|
899
|
+
// Determine mode based on which fields have intervals/values
|
|
900
|
+
let mode = 'daily';
|
|
901
|
+
let interval = 1;
|
|
902
|
+
const recurrence = {};
|
|
903
|
+
// Hourly mode: */N in hour field or specific hours
|
|
904
|
+
if (hourPattern.isInterval && !dayPattern.hasValues && !monthPattern.hasValues) {
|
|
905
|
+
mode = 'hourly';
|
|
906
|
+
interval = hourPattern.interval || 1;
|
|
907
|
+
if (minutePattern.hasValues) {
|
|
908
|
+
recurrence.byMinute = minutePattern.values;
|
|
909
|
+
}
|
|
910
|
+
if (hourPattern.hasValues) {
|
|
911
|
+
recurrence.byHour = hourPattern.values;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
// Yearly mode: specific months or */N in month field
|
|
915
|
+
else if (monthPattern.hasValues || monthPattern.isInterval) {
|
|
916
|
+
mode = 'yearly';
|
|
917
|
+
interval = monthPattern.interval || 1;
|
|
918
|
+
if (monthPattern.hasValues) {
|
|
919
|
+
recurrence.byMonth = monthPattern.values;
|
|
920
|
+
}
|
|
921
|
+
if (dayPattern.hasValues) {
|
|
922
|
+
recurrence.byDay = dayPattern.values;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
// Monthly mode: */N in day field or specific days
|
|
926
|
+
else if (dayPattern.isInterval || (dayPattern.hasValues && !weekdayPattern.hasValues)) {
|
|
927
|
+
mode = 'monthly';
|
|
928
|
+
interval = dayPattern.interval || 1;
|
|
929
|
+
if (dayPattern.hasValues) {
|
|
930
|
+
recurrence.byDay = dayPattern.values;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
// Weekly mode: specific weekdays
|
|
934
|
+
else if (weekdayPattern.hasValues) {
|
|
935
|
+
mode = 'weekly';
|
|
936
|
+
interval = 1;
|
|
937
|
+
recurrence.byDay = weekdayPattern.values;
|
|
938
|
+
}
|
|
939
|
+
// Daily mode: default fallback
|
|
940
|
+
else {
|
|
941
|
+
mode = 'daily';
|
|
942
|
+
interval = 1;
|
|
943
|
+
}
|
|
944
|
+
return {
|
|
945
|
+
mode,
|
|
946
|
+
interval,
|
|
947
|
+
startCondition: { type: 'now', startDate: new Date() },
|
|
948
|
+
recurrence,
|
|
949
|
+
endCondition: { type: 'never' },
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
catch (error) {
|
|
953
|
+
console.error('[SchedulerPicker] Failed to parse cron expression:', error);
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Analyze a cron field to extract interval and values
|
|
959
|
+
*/
|
|
960
|
+
analyzeCronField(field) {
|
|
961
|
+
if (!field || field.length === 0) {
|
|
962
|
+
return { hasValues: false, values: [], isInterval: false, interval: null };
|
|
963
|
+
}
|
|
964
|
+
// Check if it's an interval pattern (e.g., */2 produces [0,2,4,6...])
|
|
965
|
+
const isInterval = field.length > 1 && field.length < 60;
|
|
966
|
+
let interval = null;
|
|
967
|
+
if (isInterval && field.length >= 2) {
|
|
968
|
+
// Calculate interval from difference between consecutive values
|
|
969
|
+
interval = field[1] - field[0];
|
|
970
|
+
// Verify it's consistent
|
|
971
|
+
const isConsistent = field.every((val, idx) => idx === 0 || val - field[idx - 1] === interval);
|
|
972
|
+
if (!isConsistent) {
|
|
973
|
+
interval = null;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return {
|
|
977
|
+
hasValues: field.length > 0 && field.length < 60, // Exclude wildcard (all values)
|
|
978
|
+
values: field,
|
|
979
|
+
isInterval: interval !== null,
|
|
980
|
+
interval,
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Convert pattern to RRule string (iCalendar format)
|
|
985
|
+
*/
|
|
986
|
+
async toRRule(pattern) {
|
|
987
|
+
const { RRule } = await import('rrule');
|
|
988
|
+
const rruleObj = this.toRRuleObject(pattern, RRule);
|
|
989
|
+
return rruleObj ? rruleObj.toString() : '';
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Convert RRule string to pattern
|
|
993
|
+
*/
|
|
994
|
+
async fromRRule(rruleStr) {
|
|
995
|
+
try {
|
|
996
|
+
const { RRule, rrulestr } = await import('rrule');
|
|
997
|
+
const rrule = rrulestr(rruleStr);
|
|
998
|
+
// Convert RRule options back to our pattern
|
|
999
|
+
const options = rrule.origOptions;
|
|
1000
|
+
let mode = 'daily';
|
|
1001
|
+
if (options.freq === RRule.HOURLY)
|
|
1002
|
+
mode = 'hourly';
|
|
1003
|
+
else if (options.freq === RRule.DAILY)
|
|
1004
|
+
mode = 'daily';
|
|
1005
|
+
else if (options.freq === RRule.WEEKLY)
|
|
1006
|
+
mode = 'weekly';
|
|
1007
|
+
else if (options.freq === RRule.MONTHLY)
|
|
1008
|
+
mode = 'monthly';
|
|
1009
|
+
else if (options.freq === RRule.YEARLY)
|
|
1010
|
+
mode = 'yearly';
|
|
1011
|
+
return {
|
|
1012
|
+
mode,
|
|
1013
|
+
interval: options.interval || 1,
|
|
1014
|
+
startCondition: { type: 'now', startDate: new Date() },
|
|
1015
|
+
recurrence: {
|
|
1016
|
+
byDay: options.byweekday,
|
|
1017
|
+
byMonth: options.bymonth,
|
|
1018
|
+
byHour: options.byhour,
|
|
1019
|
+
byMinute: options.byminute,
|
|
1020
|
+
},
|
|
1021
|
+
endCondition: {
|
|
1022
|
+
type: options.count ? 'afterOccurrences' : options.until ? 'byDate' : 'never',
|
|
1023
|
+
occurrences: options.count,
|
|
1024
|
+
endDate: options.until,
|
|
1025
|
+
},
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
catch {
|
|
1029
|
+
return null;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Generate human-readable description
|
|
1034
|
+
* Uses lazy-loaded cronstrue library for i18n
|
|
1035
|
+
*/
|
|
1036
|
+
async toNaturalLanguage(pattern, locale) {
|
|
1037
|
+
const lang = locale || 'en-US';
|
|
1038
|
+
// Build natural language string based on pattern
|
|
1039
|
+
const parts = [];
|
|
1040
|
+
// Interval part
|
|
1041
|
+
const intervalKey = `@acorex:schedulerPicker.naturalLanguage.every${pattern.mode.charAt(0).toUpperCase() + pattern.mode.slice(1)}`;
|
|
1042
|
+
const intervalText = await this.translationService.translateAsync(intervalKey, {
|
|
1043
|
+
params: { count: pattern.interval },
|
|
1044
|
+
});
|
|
1045
|
+
parts.push(intervalText);
|
|
1046
|
+
// Recurrence part
|
|
1047
|
+
if (pattern.mode === 'weekly' && pattern.recurrence.byDay) {
|
|
1048
|
+
const days = await this.getDayNames(pattern.recurrence.byDay);
|
|
1049
|
+
parts.push(await this.translationService.translateAsync('@acorex:schedulerPicker.naturalLanguage.onDays', {
|
|
1050
|
+
params: { days: days.join(', ') },
|
|
1051
|
+
}));
|
|
1052
|
+
}
|
|
1053
|
+
if (pattern.mode === 'monthly') {
|
|
1054
|
+
if (pattern.recurrence.byOccurrence && pattern.recurrence.byOccurrence.length > 0) {
|
|
1055
|
+
// e.g., "on the 2nd Monday"
|
|
1056
|
+
const occ = pattern.recurrence.byOccurrence[0];
|
|
1057
|
+
const positionText = await this.getOccurrencePositionText(occ.position);
|
|
1058
|
+
const dayName = await this.translationService.translateAsync(`@acorex:schedulerPicker.days.${getDayTranslationKey(occ.dayOfWeek)}`);
|
|
1059
|
+
const onThe = await this.translationService.translateAsync('@acorex:schedulerPicker.naturalLanguage.onThe');
|
|
1060
|
+
parts.push(`${onThe} ${positionText} ${dayName}`);
|
|
1061
|
+
}
|
|
1062
|
+
else if (pattern.recurrence.byDay && pattern.recurrence.byDay.length > 0) {
|
|
1063
|
+
// e.g., "on day 15" or "on days 1, 15, 30"
|
|
1064
|
+
const dayList = pattern.recurrence.byDay.join(', ');
|
|
1065
|
+
const onDayKey = pattern.recurrence.byDay.length > 1 ? '@acorex:schedulerPicker.naturalLanguage.onDaysPlural' : '@acorex:schedulerPicker.naturalLanguage.onDay';
|
|
1066
|
+
const onDay = await this.translationService.translateAsync(onDayKey);
|
|
1067
|
+
parts.push(`${onDay} ${dayList}`);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
if (pattern.mode === 'yearly') {
|
|
1071
|
+
const yearlyParts = [];
|
|
1072
|
+
// Month part
|
|
1073
|
+
if (pattern.recurrence.byMonth && pattern.recurrence.byMonth.length > 0) {
|
|
1074
|
+
const months = await this.getMonthNames(pattern.recurrence.byMonth);
|
|
1075
|
+
const inWord = await this.translationService.translateAsync('@acorex:schedulerPicker.naturalLanguage.in');
|
|
1076
|
+
yearlyParts.push(`${inWord} ${months.join(', ')}`);
|
|
1077
|
+
}
|
|
1078
|
+
// Day/Occurrence part
|
|
1079
|
+
if (pattern.recurrence.byOccurrence && pattern.recurrence.byOccurrence.length > 0) {
|
|
1080
|
+
// e.g., "on the 2nd Monday"
|
|
1081
|
+
const occ = pattern.recurrence.byOccurrence[0];
|
|
1082
|
+
const positionText = await this.getOccurrencePositionText(occ.position);
|
|
1083
|
+
const dayName = await this.translationService.translateAsync(`@acorex:schedulerPicker.days.${getDayTranslationKey(occ.dayOfWeek)}`);
|
|
1084
|
+
const onThe = await this.translationService.translateAsync('@acorex:schedulerPicker.naturalLanguage.onThe');
|
|
1085
|
+
yearlyParts.push(`${onThe} ${positionText} ${dayName}`);
|
|
1086
|
+
}
|
|
1087
|
+
else if (pattern.recurrence.byDay && pattern.recurrence.byDay.length > 0) {
|
|
1088
|
+
// e.g., "on day 15" or "on days 1, 15, 30"
|
|
1089
|
+
const dayList = pattern.recurrence.byDay.join(', ');
|
|
1090
|
+
const onDayKey = pattern.recurrence.byDay.length > 1 ? '@acorex:schedulerPicker.naturalLanguage.onDaysPlural' : '@acorex:schedulerPicker.naturalLanguage.onDay';
|
|
1091
|
+
const onDay = await this.translationService.translateAsync(onDayKey);
|
|
1092
|
+
yearlyParts.push(`${onDay} ${dayList}`);
|
|
1093
|
+
}
|
|
1094
|
+
if (yearlyParts.length > 0) {
|
|
1095
|
+
parts.push(yearlyParts.join(' '));
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
// Start condition part
|
|
1099
|
+
if (pattern.startCondition.type === 'byDate' && pattern.startCondition.startDate) {
|
|
1100
|
+
parts.push(await this.translationService.translateAsync('@acorex:schedulerPicker.naturalLanguage.startingFrom', {
|
|
1101
|
+
params: { date: pattern.startCondition.startDate.toLocaleDateString(lang) },
|
|
1102
|
+
}));
|
|
1103
|
+
}
|
|
1104
|
+
// End condition part
|
|
1105
|
+
if (pattern.endCondition.type === 'afterOccurrences') {
|
|
1106
|
+
parts.push(await this.translationService.translateAsync('@acorex:schedulerPicker.naturalLanguage.forOccurrences', {
|
|
1107
|
+
params: { count: pattern.endCondition.occurrences },
|
|
1108
|
+
}));
|
|
1109
|
+
}
|
|
1110
|
+
else if (pattern.endCondition.type === 'byDate' && pattern.endCondition.endDate) {
|
|
1111
|
+
parts.push(await this.translationService.translateAsync('@acorex:schedulerPicker.naturalLanguage.until', {
|
|
1112
|
+
params: { date: pattern.endCondition.endDate.toLocaleDateString(lang) },
|
|
1113
|
+
}));
|
|
1114
|
+
}
|
|
1115
|
+
return parts.join(' ');
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Validate pattern against config and rules
|
|
1119
|
+
*/
|
|
1120
|
+
async validatePattern(pattern, settings) {
|
|
1121
|
+
const errors = [];
|
|
1122
|
+
// Required fields
|
|
1123
|
+
if (!pattern.mode) {
|
|
1124
|
+
errors.push({
|
|
1125
|
+
field: 'mode',
|
|
1126
|
+
code: 'required',
|
|
1127
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.modeRequired'),
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
if (!pattern.interval || pattern.interval < 1) {
|
|
1131
|
+
errors.push({
|
|
1132
|
+
field: 'interval',
|
|
1133
|
+
code: 'required',
|
|
1134
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.intervalRequired'),
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
// Interval constraints
|
|
1138
|
+
if (settings.minInterval && pattern.interval < settings.minInterval) {
|
|
1139
|
+
errors.push({
|
|
1140
|
+
field: 'interval',
|
|
1141
|
+
code: 'outOfRange',
|
|
1142
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.intervalTooSmall', {
|
|
1143
|
+
params: { min: settings.minInterval },
|
|
1144
|
+
}),
|
|
1145
|
+
params: { min: settings.minInterval },
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
if (settings.maxInterval && pattern.interval > settings.maxInterval) {
|
|
1149
|
+
errors.push({
|
|
1150
|
+
field: 'interval',
|
|
1151
|
+
code: 'outOfRange',
|
|
1152
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.intervalTooLarge', {
|
|
1153
|
+
params: { max: settings.maxInterval },
|
|
1154
|
+
}),
|
|
1155
|
+
params: { max: settings.maxInterval },
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
// Mode-specific recurrence validation
|
|
1159
|
+
if (pattern.mode === 'monthly') {
|
|
1160
|
+
const hasByDay = pattern.recurrence.byDay && pattern.recurrence.byDay.length > 0;
|
|
1161
|
+
const hasByOccurrence = pattern.recurrence.byOccurrence && pattern.recurrence.byOccurrence.length > 0;
|
|
1162
|
+
// Conflict: Cannot have both day of month and occurrence pattern
|
|
1163
|
+
if (hasByDay && hasByOccurrence) {
|
|
1164
|
+
errors.push({
|
|
1165
|
+
field: 'recurrence',
|
|
1166
|
+
code: 'conflict',
|
|
1167
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.cannotCombineDayAndOccurrence'),
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
// Yearly mode: Validate occurrence conflicts
|
|
1172
|
+
if (pattern.mode === 'yearly') {
|
|
1173
|
+
const hasByDay = pattern.recurrence.byDay && pattern.recurrence.byDay.length > 0;
|
|
1174
|
+
const hasByOccurrence = pattern.recurrence.byOccurrence && pattern.recurrence.byOccurrence.length > 0;
|
|
1175
|
+
if (hasByDay && hasByOccurrence) {
|
|
1176
|
+
errors.push({
|
|
1177
|
+
field: 'recurrence',
|
|
1178
|
+
code: 'conflict',
|
|
1179
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.cannotCombineDayAndOccurrence'),
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
// Validate exclusions and inclusions size for performance
|
|
1184
|
+
const maxDateArraySize = 1000; // Prevent excessive memory usage
|
|
1185
|
+
if (pattern.exclusions && pattern.exclusions.length > maxDateArraySize) {
|
|
1186
|
+
errors.push({
|
|
1187
|
+
field: 'exclusions',
|
|
1188
|
+
code: 'outOfRange',
|
|
1189
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.tooManyExclusions', {
|
|
1190
|
+
params: { max: maxDateArraySize },
|
|
1191
|
+
}),
|
|
1192
|
+
params: { max: maxDateArraySize },
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
if (pattern.inclusions && pattern.inclusions.length > maxDateArraySize) {
|
|
1196
|
+
errors.push({
|
|
1197
|
+
field: 'inclusions',
|
|
1198
|
+
code: 'outOfRange',
|
|
1199
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.tooManyInclusions', {
|
|
1200
|
+
params: { max: maxDateArraySize },
|
|
1201
|
+
}),
|
|
1202
|
+
params: { max: maxDateArraySize },
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
// End date validation
|
|
1206
|
+
if (pattern.endCondition.type === 'byDate' && pattern.endCondition.endDate) {
|
|
1207
|
+
if (pattern.endCondition.endDate < new Date()) {
|
|
1208
|
+
errors.push({
|
|
1209
|
+
field: 'endCondition.endDate',
|
|
1210
|
+
code: 'pastDate',
|
|
1211
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.endDateInPast'),
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
if (settings.maxDate && pattern.endCondition.endDate > settings.maxDate) {
|
|
1215
|
+
errors.push({
|
|
1216
|
+
field: 'endCondition.endDate',
|
|
1217
|
+
code: 'outOfRange',
|
|
1218
|
+
message: await this.translationService.translateAsync('@acorex:schedulerPicker.validation.endDateTooFar', {
|
|
1219
|
+
params: { maxDate: settings.maxDate.toLocaleDateString() },
|
|
1220
|
+
}),
|
|
1221
|
+
params: { maxDate: settings.maxDate },
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
// Custom validators
|
|
1226
|
+
if (settings.customValidators) {
|
|
1227
|
+
for (const validator of settings.customValidators) {
|
|
1228
|
+
const error = validator(pattern, settings);
|
|
1229
|
+
if (error) {
|
|
1230
|
+
errors.push(error);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
return errors;
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Check if a specific date matches the pattern
|
|
1238
|
+
*/
|
|
1239
|
+
async isDateMatch(pattern, date) {
|
|
1240
|
+
const { RRule } = await import('rrule');
|
|
1241
|
+
const rruleObj = this.toRRuleObject(pattern, RRule);
|
|
1242
|
+
if (!rruleObj) {
|
|
1243
|
+
return false;
|
|
1244
|
+
}
|
|
1245
|
+
// Check if date is in the generated occurrences
|
|
1246
|
+
const occurrences = rruleObj.between(new Date(date.getTime() - 1000), new Date(date.getTime() + 1000), true);
|
|
1247
|
+
return occurrences.length > 0;
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Get next occurrence from a specific date
|
|
1251
|
+
*/
|
|
1252
|
+
async getNextOccurrence(pattern, from) {
|
|
1253
|
+
const { RRule } = await import('rrule');
|
|
1254
|
+
const rruleObj = this.toRRuleObject(pattern, RRule);
|
|
1255
|
+
if (!rruleObj) {
|
|
1256
|
+
return null;
|
|
1257
|
+
}
|
|
1258
|
+
return rruleObj.after(from, false) || null;
|
|
1259
|
+
}
|
|
1260
|
+
/**
|
|
1261
|
+
* Convert pattern to RRule object
|
|
1262
|
+
* Helper method for RRule operations
|
|
1263
|
+
*/
|
|
1264
|
+
toRRuleObject(pattern, RRule) {
|
|
1265
|
+
const options = {
|
|
1266
|
+
interval: pattern.interval,
|
|
1267
|
+
};
|
|
1268
|
+
// Set frequency
|
|
1269
|
+
switch (pattern.mode) {
|
|
1270
|
+
case 'hourly':
|
|
1271
|
+
options.freq = RRule.HOURLY;
|
|
1272
|
+
break;
|
|
1273
|
+
case 'daily':
|
|
1274
|
+
options.freq = RRule.DAILY;
|
|
1275
|
+
break;
|
|
1276
|
+
case 'weekly':
|
|
1277
|
+
options.freq = RRule.WEEKLY;
|
|
1278
|
+
break;
|
|
1279
|
+
case 'monthly':
|
|
1280
|
+
options.freq = RRule.MONTHLY;
|
|
1281
|
+
break;
|
|
1282
|
+
case 'yearly':
|
|
1283
|
+
options.freq = RRule.YEARLY;
|
|
1284
|
+
break;
|
|
1285
|
+
}
|
|
1286
|
+
// Set recurrence rules
|
|
1287
|
+
if (pattern.recurrence.byDay) {
|
|
1288
|
+
if (pattern.mode === 'weekly') {
|
|
1289
|
+
options.byweekday = pattern.recurrence.byDay;
|
|
1290
|
+
}
|
|
1291
|
+
else if (pattern.mode === 'monthly' || pattern.mode === 'yearly') {
|
|
1292
|
+
options.bymonthday = pattern.recurrence.byDay;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
if (pattern.recurrence.byMonth) {
|
|
1296
|
+
options.bymonth = pattern.recurrence.byMonth;
|
|
1297
|
+
}
|
|
1298
|
+
if (pattern.recurrence.byHour) {
|
|
1299
|
+
options.byhour = pattern.recurrence.byHour;
|
|
1300
|
+
}
|
|
1301
|
+
if (pattern.recurrence.byMinute) {
|
|
1302
|
+
options.byminute = pattern.recurrence.byMinute;
|
|
1303
|
+
}
|
|
1304
|
+
// Set occurrence rules
|
|
1305
|
+
if (pattern.recurrence.byOccurrence) {
|
|
1306
|
+
// RRule format for "first Monday" etc.
|
|
1307
|
+
options.byweekday = pattern.recurrence.byOccurrence.map((occ) => {
|
|
1308
|
+
return RRule[this.getDayName(occ.dayOfWeek)].nth(occ.position);
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
// Set end condition
|
|
1312
|
+
switch (pattern.endCondition.type) {
|
|
1313
|
+
case 'afterOccurrences':
|
|
1314
|
+
options.count = pattern.endCondition.occurrences;
|
|
1315
|
+
break;
|
|
1316
|
+
case 'byDate':
|
|
1317
|
+
options.until = pattern.endCondition.endDate;
|
|
1318
|
+
break;
|
|
1319
|
+
}
|
|
1320
|
+
try {
|
|
1321
|
+
return new RRule(options);
|
|
1322
|
+
}
|
|
1323
|
+
catch {
|
|
1324
|
+
return null;
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
/**
|
|
1328
|
+
* Get day name constant for RRule
|
|
1329
|
+
*/
|
|
1330
|
+
getDayName(dayIndex) {
|
|
1331
|
+
return getRRuleDayKey(dayIndex);
|
|
1332
|
+
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Get localized day names
|
|
1335
|
+
*/
|
|
1336
|
+
async getDayNames(dayIndices) {
|
|
1337
|
+
return Promise.all(dayIndices.map((index) => this.translationService.translateAsync(`@acorex:schedulerPicker.days.${getDayTranslationKey(index)}`)));
|
|
1338
|
+
}
|
|
1339
|
+
/**
|
|
1340
|
+
* Get localized month names
|
|
1341
|
+
*/
|
|
1342
|
+
async getMonthNames(monthIndices) {
|
|
1343
|
+
const monthKeys = [
|
|
1344
|
+
'january',
|
|
1345
|
+
'february',
|
|
1346
|
+
'march',
|
|
1347
|
+
'april',
|
|
1348
|
+
'may',
|
|
1349
|
+
'june',
|
|
1350
|
+
'july',
|
|
1351
|
+
'august',
|
|
1352
|
+
'september',
|
|
1353
|
+
'october',
|
|
1354
|
+
'november',
|
|
1355
|
+
'december',
|
|
1356
|
+
];
|
|
1357
|
+
return Promise.all(monthIndices.map((index) => this.translationService.translateAsync(`@acorex:schedulerPicker.months.${monthKeys[index]}`)));
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Get text for occurrence position
|
|
1361
|
+
*/
|
|
1362
|
+
async getOccurrencePositionText(position) {
|
|
1363
|
+
const ordinalKeys = {
|
|
1364
|
+
1: '1st',
|
|
1365
|
+
2: '2nd',
|
|
1366
|
+
3: '3rd',
|
|
1367
|
+
4: '4th',
|
|
1368
|
+
'-1': 'last',
|
|
1369
|
+
};
|
|
1370
|
+
const key = ordinalKeys[position] || '1st';
|
|
1371
|
+
return this.translationService.translateAsync(`@acorex:schedulerPicker.ordinals.${key}`);
|
|
1372
|
+
}
|
|
1373
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1374
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerService, providedIn: 'root' }); }
|
|
1375
|
+
}
|
|
1376
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerService, decorators: [{
|
|
1377
|
+
type: Injectable,
|
|
1378
|
+
args: [{
|
|
1379
|
+
providedIn: 'root',
|
|
1380
|
+
}]
|
|
1381
|
+
}] });
|
|
1382
|
+
|
|
1383
|
+
class AXSchedulerPickerStartConditionSelectorComponent {
|
|
1384
|
+
constructor() {
|
|
1385
|
+
this.startCondition = input(...(ngDevMode ? [undefined, { debugName: "startCondition" }] : []));
|
|
1386
|
+
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
1387
|
+
this.startConditionChange = output();
|
|
1388
|
+
this.selectedType = signal('now', ...(ngDevMode ? [{ debugName: "selectedType" }] : []));
|
|
1389
|
+
this.startDate = signal(null, ...(ngDevMode ? [{ debugName: "startDate" }] : []));
|
|
1390
|
+
this.startTypeItems = [
|
|
1391
|
+
{ id: 'now', text: '@acorex:schedulerPicker.startCondition.now' },
|
|
1392
|
+
{ id: 'byDate', text: '@acorex:schedulerPicker.startCondition.byDate' },
|
|
1393
|
+
];
|
|
1394
|
+
// Initialize from input
|
|
1395
|
+
effect(() => {
|
|
1396
|
+
const condition = this.startCondition();
|
|
1397
|
+
if (condition) {
|
|
1398
|
+
this.selectedType.set(condition.type);
|
|
1399
|
+
this.startDate.set(condition.startDate);
|
|
1400
|
+
}
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
onTypeChange(event) {
|
|
1404
|
+
this.selectedType.set(event.value);
|
|
1405
|
+
this.emitChange();
|
|
1406
|
+
}
|
|
1407
|
+
onDateChange(value) {
|
|
1408
|
+
this.startDate.set(value);
|
|
1409
|
+
this.emitChange();
|
|
1410
|
+
}
|
|
1411
|
+
emitChange() {
|
|
1412
|
+
const type = this.selectedType();
|
|
1413
|
+
const condition = {
|
|
1414
|
+
type,
|
|
1415
|
+
startDate: type === 'byDate' ? this.startDate() || new Date() : new Date(),
|
|
1416
|
+
};
|
|
1417
|
+
this.startConditionChange.emit(condition);
|
|
1418
|
+
}
|
|
1419
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerStartConditionSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1420
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerStartConditionSelectorComponent, isStandalone: true, selector: "ax-scheduler-picker-start-condition-selector", inputs: { startCondition: { classPropertyName: "startCondition", publicName: "startCondition", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { startConditionChange: "startConditionChange" }, ngImport: i0, template: "<div class=\"ax-scheduler-picker-start-condition-selector\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.startCondition' | translate | async }}\n </label>\n\n <ax-selection-list\n [items]=\"startTypeItems\"\n [multiple]=\"false\"\n [showControl]=\"true\"\n [look]=\"'solid'\"\n [direction]=\"'horizontal'\"\n [value]=\"selectedType()\"\n (onValueChanged)=\"onTypeChange($event)\"\n />\n\n @if (selectedType() === 'byDate') {\n <div class=\"ax-scheduler-picker-input-group\">\n <label class=\"ax-scheduler-picker-sublabel\">\n {{ '@acorex:schedulerPicker.labels.startDate' | translate | async }}\n </label>\n <ax-datetime-box [value]=\"startDate()\" [picker]=\"'datetime'\" (valueChange)=\"onDateChange($event)\" />\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-start-condition-selector{display:flex;flex-direction:column;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "component", type: i1.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: AXDateTimeBoxComponent, selector: "ax-datetime-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "depth", "id", "type", "look", "holidayDates", "allowTyping", "picker", "calendar", "weekend", "weekdays", "format"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "onOpened", "onClosed", "readonlyChange", "disabledChange", "formatChange"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1421
|
+
}
|
|
1422
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerStartConditionSelectorComponent, decorators: [{
|
|
1423
|
+
type: Component,
|
|
1424
|
+
args: [{ selector: 'ax-scheduler-picker-start-condition-selector', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [FormsModule, AXSelectionListModule, AXDateTimeBoxComponent, AXTranslatorPipe, AsyncPipe], template: "<div class=\"ax-scheduler-picker-start-condition-selector\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.startCondition' | translate | async }}\n </label>\n\n <ax-selection-list\n [items]=\"startTypeItems\"\n [multiple]=\"false\"\n [showControl]=\"true\"\n [look]=\"'solid'\"\n [direction]=\"'horizontal'\"\n [value]=\"selectedType()\"\n (onValueChanged)=\"onTypeChange($event)\"\n />\n\n @if (selectedType() === 'byDate') {\n <div class=\"ax-scheduler-picker-input-group\">\n <label class=\"ax-scheduler-picker-sublabel\">\n {{ '@acorex:schedulerPicker.labels.startDate' | translate | async }}\n </label>\n <ax-datetime-box [value]=\"startDate()\" [picker]=\"'datetime'\" (valueChange)=\"onDateChange($event)\" />\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-start-condition-selector{display:flex;flex-direction:column;gap:.5rem}\n"] }]
|
|
1425
|
+
}], ctorParameters: () => [], propDecorators: { startCondition: [{ type: i0.Input, args: [{ isSignal: true, alias: "startCondition", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], startConditionChange: [{ type: i0.Output, args: ["startConditionChange"] }] } });
|
|
1426
|
+
|
|
1427
|
+
class AXSchedulerPickerEndConditionSelectorComponent {
|
|
1428
|
+
constructor() {
|
|
1429
|
+
this.endCondition = input(...(ngDevMode ? [undefined, { debugName: "endCondition" }] : []));
|
|
1430
|
+
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
1431
|
+
this.endConditionChange = output();
|
|
1432
|
+
this.selectedType = signal('never', ...(ngDevMode ? [{ debugName: "selectedType" }] : []));
|
|
1433
|
+
this.occurrences = signal(AX_SCHEDULER_PICKER_DEFAULT_OCCURRENCES, ...(ngDevMode ? [{ debugName: "occurrences" }] : []));
|
|
1434
|
+
this.endDate = signal(null, ...(ngDevMode ? [{ debugName: "endDate" }] : []));
|
|
1435
|
+
this.endTypeItems = [
|
|
1436
|
+
{ id: 'never', text: '@acorex:schedulerPicker.endCondition.never' },
|
|
1437
|
+
{ id: 'afterOccurrences', text: '@acorex:schedulerPicker.endCondition.afterOccurrences' },
|
|
1438
|
+
{ id: 'byDate', text: '@acorex:schedulerPicker.endCondition.byDate' },
|
|
1439
|
+
];
|
|
1440
|
+
// Sync input with internal state
|
|
1441
|
+
effect(() => {
|
|
1442
|
+
const condition = this.endCondition();
|
|
1443
|
+
if (condition) {
|
|
1444
|
+
this.selectedType.set(condition.type);
|
|
1445
|
+
if (condition.type === 'afterOccurrences' && condition.occurrences) {
|
|
1446
|
+
this.occurrences.set(condition.occurrences);
|
|
1447
|
+
}
|
|
1448
|
+
if (condition.type === 'byDate' && condition.endDate) {
|
|
1449
|
+
this.endDate.set(condition.endDate);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
onTypeChange(event) {
|
|
1455
|
+
this.selectedType.set(event.value);
|
|
1456
|
+
this.emitChange();
|
|
1457
|
+
}
|
|
1458
|
+
onOccurrencesChange(value) {
|
|
1459
|
+
this.occurrences.set(value);
|
|
1460
|
+
this.emitChange();
|
|
1461
|
+
}
|
|
1462
|
+
onDateChange(value) {
|
|
1463
|
+
this.endDate.set(value);
|
|
1464
|
+
this.emitChange();
|
|
1465
|
+
}
|
|
1466
|
+
emitChange() {
|
|
1467
|
+
const type = this.selectedType();
|
|
1468
|
+
let condition;
|
|
1469
|
+
switch (type) {
|
|
1470
|
+
case 'afterOccurrences':
|
|
1471
|
+
condition = { type: 'afterOccurrences', occurrences: this.occurrences() };
|
|
1472
|
+
break;
|
|
1473
|
+
case 'byDate':
|
|
1474
|
+
condition = { type: 'byDate', endDate: this.endDate() || new Date() };
|
|
1475
|
+
break;
|
|
1476
|
+
default:
|
|
1477
|
+
condition = { type: 'never' };
|
|
1478
|
+
}
|
|
1479
|
+
this.endConditionChange.emit(condition);
|
|
1480
|
+
}
|
|
1481
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerEndConditionSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1482
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerEndConditionSelectorComponent, isStandalone: true, selector: "ax-scheduler-picker-end-condition-selector", inputs: { endCondition: { classPropertyName: "endCondition", publicName: "endCondition", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { endConditionChange: "endConditionChange" }, ngImport: i0, template: "<div class=\"ax-scheduler-picker-end-condition-selector\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.endCondition' | translate | async }}\n </label>\n\n <ax-selection-list\n [items]=\"endTypeItems\"\n [multiple]=\"false\"\n [showControl]=\"true\"\n [look]=\"'solid'\"\n [direction]=\"'horizontal'\"\n [value]=\"selectedType()\"\n (onValueChanged)=\"onTypeChange($event)\"\n />\n\n @if (selectedType() === 'afterOccurrences') {\n <div class=\"ax-scheduler-picker-input-group\">\n <label class=\"ax-scheduler-picker-sublabel\">\n {{ '@acorex:schedulerPicker.labels.numberOfOccurrences' | translate | async }}\n </label>\n <ax-number-box [value]=\"occurrences()\" (valueChange)=\"onOccurrencesChange($event)\" />\n </div>\n }\n\n @if (selectedType() === 'byDate') {\n <div class=\"ax-scheduler-picker-input-group\">\n <label class=\"ax-scheduler-picker-sublabel\">\n {{ '@acorex:schedulerPicker.labels.endDate' | translate | async }}\n </label>\n <ax-datetime-box [value]=\"endDate()\" mode=\"date\" (valueChange)=\"onDateChange($event)\" />\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-end-condition-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-input-group{display:flex;flex-direction:column;gap:.375rem;padding-left:.5rem}.ax-scheduler-picker-label,.ax-scheduler-picker-sublabel{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}ax-selection-list{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "component", type: i1.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: AXNumberBoxComponent, selector: "ax-number-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "minValue", "maxValue", "showSpinButtons", "thousandsSeparator", "decimals", "changeOnScroll", "step"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "thousandsSeparatorChange"] }, { kind: "component", type: AXDateTimeBoxComponent, selector: "ax-datetime-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "depth", "id", "type", "look", "holidayDates", "allowTyping", "picker", "calendar", "weekend", "weekdays", "format"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "onOpened", "onClosed", "readonlyChange", "disabledChange", "formatChange"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1483
|
+
}
|
|
1484
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerEndConditionSelectorComponent, decorators: [{
|
|
1485
|
+
type: Component,
|
|
1486
|
+
args: [{ selector: 'ax-scheduler-picker-end-condition-selector', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
1487
|
+
FormsModule,
|
|
1488
|
+
AXSelectionListModule,
|
|
1489
|
+
AXNumberBoxComponent,
|
|
1490
|
+
AXDateTimeBoxComponent,
|
|
1491
|
+
AXTranslatorPipe,
|
|
1492
|
+
AsyncPipe,
|
|
1493
|
+
], template: "<div class=\"ax-scheduler-picker-end-condition-selector\">\n <label class=\"ax-scheduler-picker-label\">\n {{ '@acorex:schedulerPicker.labels.endCondition' | translate | async }}\n </label>\n\n <ax-selection-list\n [items]=\"endTypeItems\"\n [multiple]=\"false\"\n [showControl]=\"true\"\n [look]=\"'solid'\"\n [direction]=\"'horizontal'\"\n [value]=\"selectedType()\"\n (onValueChanged)=\"onTypeChange($event)\"\n />\n\n @if (selectedType() === 'afterOccurrences') {\n <div class=\"ax-scheduler-picker-input-group\">\n <label class=\"ax-scheduler-picker-sublabel\">\n {{ '@acorex:schedulerPicker.labels.numberOfOccurrences' | translate | async }}\n </label>\n <ax-number-box [value]=\"occurrences()\" (valueChange)=\"onOccurrencesChange($event)\" />\n </div>\n }\n\n @if (selectedType() === 'byDate') {\n <div class=\"ax-scheduler-picker-input-group\">\n <label class=\"ax-scheduler-picker-sublabel\">\n {{ '@acorex:schedulerPicker.labels.endDate' | translate | async }}\n </label>\n <ax-datetime-box [value]=\"endDate()\" mode=\"date\" (valueChange)=\"onDateChange($event)\" />\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-end-condition-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-input-group{display:flex;flex-direction:column;gap:.375rem;padding-left:.5rem}.ax-scheduler-picker-label,.ax-scheduler-picker-sublabel{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}ax-selection-list{width:100%}\n"] }]
|
|
1494
|
+
}], ctorParameters: () => [], propDecorators: { endCondition: [{ type: i0.Input, args: [{ isSignal: true, alias: "endCondition", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], endConditionChange: [{ type: i0.Output, args: ["endConditionChange"] }] } });
|
|
1495
|
+
|
|
1496
|
+
class AXSchedulerPickerExclusionManagerComponent {
|
|
1497
|
+
constructor() {
|
|
1498
|
+
this.exclusions = input(...(ngDevMode ? [undefined, { debugName: "exclusions" }] : []));
|
|
1499
|
+
this.config = input(...(ngDevMode ? [undefined, { debugName: "config" }] : []));
|
|
1500
|
+
this.exclusionsChange = output();
|
|
1501
|
+
this.newExclusionDate = signal(null, ...(ngDevMode ? [{ debugName: "newExclusionDate" }] : []));
|
|
1502
|
+
this.exclusionList = signal([], ...(ngDevMode ? [{ debugName: "exclusionList" }] : []));
|
|
1503
|
+
// Sync input with internal list
|
|
1504
|
+
effect(() => {
|
|
1505
|
+
const exclusions = this.exclusions();
|
|
1506
|
+
this.exclusionList.set(exclusions || []);
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
addExclusion() {
|
|
1510
|
+
const date = this.newExclusionDate();
|
|
1511
|
+
if (date) {
|
|
1512
|
+
// Normalize date to midnight
|
|
1513
|
+
const normalized = normalizeDate(date);
|
|
1514
|
+
// Check for duplicates
|
|
1515
|
+
if (!dateExistsInArray(normalized, this.exclusionList())) {
|
|
1516
|
+
const updated = [...this.exclusionList(), normalized];
|
|
1517
|
+
this.exclusionList.set(updated);
|
|
1518
|
+
this.exclusionsChange.emit(updated);
|
|
1519
|
+
}
|
|
1520
|
+
this.newExclusionDate.set(null);
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
removeExclusion(date) {
|
|
1524
|
+
const normalized = normalizeDate(date);
|
|
1525
|
+
const updated = this.exclusionList().filter((d) => normalizeDate(d).getTime() !== normalized.getTime());
|
|
1526
|
+
this.exclusionList.set(updated);
|
|
1527
|
+
this.exclusionsChange.emit(updated);
|
|
1528
|
+
}
|
|
1529
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerExclusionManagerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1530
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerExclusionManagerComponent, isStandalone: true, selector: "ax-scheduler-picker-exclusion-manager", inputs: { exclusions: { classPropertyName: "exclusions", publicName: "exclusions", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { exclusionsChange: "exclusionsChange" }, host: { classAttribute: "ax-scheduler-picker-exclusion-manager-host" }, ngImport: i0, template: `
|
|
1531
|
+
<div class="ax-scheduler-picker-exclusion-manager">
|
|
1532
|
+
<div class="ax-scheduler-picker-section-header">
|
|
1533
|
+
<label class="ax-scheduler-picker-label">
|
|
1534
|
+
<i class="ax-icon ax-icon-calendar-remove"></i>
|
|
1535
|
+
{{ '@acorex:schedulerPicker.labels.excludeDates' | translate | async }}
|
|
1536
|
+
</label>
|
|
1537
|
+
@if (exclusionList().length > 0) {
|
|
1538
|
+
<ax-badge [text]="exclusionList().length.toString()"></ax-badge>
|
|
1539
|
+
}
|
|
1540
|
+
</div>
|
|
1541
|
+
|
|
1542
|
+
<div class="ax-scheduler-picker-add-section">
|
|
1543
|
+
<ax-datetime-box
|
|
1544
|
+
class="ax-scheduler-picker-date-input"
|
|
1545
|
+
[value]="newExclusionDate()"
|
|
1546
|
+
mode="date"
|
|
1547
|
+
(valueChange)="newExclusionDate.set($event)"
|
|
1548
|
+
[placeholder]="'@acorex:schedulerPicker.placeholders.selectExclusionDate' | translate | async"
|
|
1549
|
+
/>
|
|
1550
|
+
<ax-button
|
|
1551
|
+
mode="success"
|
|
1552
|
+
[text]="'@acorex:common.actions.add' | translate | async"
|
|
1553
|
+
(click)="addExclusion()"
|
|
1554
|
+
[disabled]="!newExclusionDate()"
|
|
1555
|
+
>
|
|
1556
|
+
<ax-prefix>
|
|
1557
|
+
<i class="ax-icon ax-icon-plus"></i>
|
|
1558
|
+
</ax-prefix>
|
|
1559
|
+
</ax-button>
|
|
1560
|
+
</div>
|
|
1561
|
+
|
|
1562
|
+
@if (exclusionList().length > 0) {
|
|
1563
|
+
<div class="ax-scheduler-picker-chips-container">
|
|
1564
|
+
@for (date of exclusionList(); track date.getTime()) {
|
|
1565
|
+
<ax-chips [text]="date | date: 'mediumDate'" color="danger" (click)="removeExclusion(date)">
|
|
1566
|
+
<ax-prefix>
|
|
1567
|
+
<i class="ax-icon ax-icon-calendar"></i>
|
|
1568
|
+
</ax-prefix>
|
|
1569
|
+
<ax-suffix>
|
|
1570
|
+
<i class="ax-icon ax-icon-close"></i>
|
|
1571
|
+
</ax-suffix>
|
|
1572
|
+
</ax-chips>
|
|
1573
|
+
}
|
|
1574
|
+
</div>
|
|
1575
|
+
} @else {
|
|
1576
|
+
<div class="ax-scheduler-picker-empty-state">
|
|
1577
|
+
<i class="ax-icon ax-icon-calendar-check"></i>
|
|
1578
|
+
<span>{{ '@acorex:schedulerPicker.messages.noExcludedDates' | translate | async }}</span>
|
|
1579
|
+
</div>
|
|
1580
|
+
}
|
|
1581
|
+
</div>
|
|
1582
|
+
`, isInline: true, styles: [".ax-scheduler-picker-exclusion-manager{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-section-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:.375rem}.ax-scheduler-picker-label{display:flex;align-items:center;gap:.375rem;color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight)}.ax-scheduler-picker-label .ax-icon{font-size:1.125rem;color:rgb(var(--ax-sys-color-danger-500))}.ax-scheduler-picker-add-section{display:flex;gap:.5rem;align-items:stretch}.ax-scheduler-picker-date-input{flex:1}.ax-scheduler-picker-chips-container{display:flex;flex-wrap:wrap;gap:.375rem}.ax-scheduler-picker-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.375rem;padding:.75rem .5rem;border:1px dashed rgb(var(--ax-sys-color-border-light-surface));border-radius:var(--ax-sys-border-radius-md);color:rgb(var(--ax-sys-color-on-darker-surface));font-size:.875rem}.ax-scheduler-picker-empty-state .ax-icon{font-size:1.5rem;opacity:.4}\n"], dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1$1.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: AXBadgeModule }, { kind: "component", type: i2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXChipsModule }, { kind: "component", type: i3.AXChipsComponent, selector: "ax-chips", inputs: ["tabIndex", "color", "look", "text"], outputs: ["textChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: AXDateTimeBoxComponent, selector: "ax-datetime-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "depth", "id", "type", "look", "holidayDates", "allowTyping", "picker", "calendar", "weekend", "weekdays", "format"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "onOpened", "onClosed", "readonlyChange", "disabledChange", "formatChange"] }, { 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: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1583
|
+
}
|
|
1584
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerExclusionManagerComponent, decorators: [{
|
|
1585
|
+
type: Component,
|
|
1586
|
+
args: [{ selector: 'ax-scheduler-picker-exclusion-manager', template: `
|
|
1587
|
+
<div class="ax-scheduler-picker-exclusion-manager">
|
|
1588
|
+
<div class="ax-scheduler-picker-section-header">
|
|
1589
|
+
<label class="ax-scheduler-picker-label">
|
|
1590
|
+
<i class="ax-icon ax-icon-calendar-remove"></i>
|
|
1591
|
+
{{ '@acorex:schedulerPicker.labels.excludeDates' | translate | async }}
|
|
1592
|
+
</label>
|
|
1593
|
+
@if (exclusionList().length > 0) {
|
|
1594
|
+
<ax-badge [text]="exclusionList().length.toString()"></ax-badge>
|
|
1595
|
+
}
|
|
1596
|
+
</div>
|
|
1597
|
+
|
|
1598
|
+
<div class="ax-scheduler-picker-add-section">
|
|
1599
|
+
<ax-datetime-box
|
|
1600
|
+
class="ax-scheduler-picker-date-input"
|
|
1601
|
+
[value]="newExclusionDate()"
|
|
1602
|
+
mode="date"
|
|
1603
|
+
(valueChange)="newExclusionDate.set($event)"
|
|
1604
|
+
[placeholder]="'@acorex:schedulerPicker.placeholders.selectExclusionDate' | translate | async"
|
|
1605
|
+
/>
|
|
1606
|
+
<ax-button
|
|
1607
|
+
mode="success"
|
|
1608
|
+
[text]="'@acorex:common.actions.add' | translate | async"
|
|
1609
|
+
(click)="addExclusion()"
|
|
1610
|
+
[disabled]="!newExclusionDate()"
|
|
1611
|
+
>
|
|
1612
|
+
<ax-prefix>
|
|
1613
|
+
<i class="ax-icon ax-icon-plus"></i>
|
|
1614
|
+
</ax-prefix>
|
|
1615
|
+
</ax-button>
|
|
1616
|
+
</div>
|
|
1617
|
+
|
|
1618
|
+
@if (exclusionList().length > 0) {
|
|
1619
|
+
<div class="ax-scheduler-picker-chips-container">
|
|
1620
|
+
@for (date of exclusionList(); track date.getTime()) {
|
|
1621
|
+
<ax-chips [text]="date | date: 'mediumDate'" color="danger" (click)="removeExclusion(date)">
|
|
1622
|
+
<ax-prefix>
|
|
1623
|
+
<i class="ax-icon ax-icon-calendar"></i>
|
|
1624
|
+
</ax-prefix>
|
|
1625
|
+
<ax-suffix>
|
|
1626
|
+
<i class="ax-icon ax-icon-close"></i>
|
|
1627
|
+
</ax-suffix>
|
|
1628
|
+
</ax-chips>
|
|
1629
|
+
}
|
|
1630
|
+
</div>
|
|
1631
|
+
} @else {
|
|
1632
|
+
<div class="ax-scheduler-picker-empty-state">
|
|
1633
|
+
<i class="ax-icon ax-icon-calendar-check"></i>
|
|
1634
|
+
<span>{{ '@acorex:schedulerPicker.messages.noExcludedDates' | translate | async }}</span>
|
|
1635
|
+
</div>
|
|
1636
|
+
}
|
|
1637
|
+
</div>
|
|
1638
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
1639
|
+
AXDecoratorModule,
|
|
1640
|
+
AXBadgeModule,
|
|
1641
|
+
AXChipsModule,
|
|
1642
|
+
FormsModule,
|
|
1643
|
+
AXDateTimeBoxComponent,
|
|
1644
|
+
AXButtonComponent,
|
|
1645
|
+
AXTranslatorPipe,
|
|
1646
|
+
AsyncPipe,
|
|
1647
|
+
DatePipe,
|
|
1648
|
+
], host: {
|
|
1649
|
+
class: 'ax-scheduler-picker-exclusion-manager-host',
|
|
1650
|
+
}, styles: [".ax-scheduler-picker-exclusion-manager{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-section-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:.375rem}.ax-scheduler-picker-label{display:flex;align-items:center;gap:.375rem;color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight)}.ax-scheduler-picker-label .ax-icon{font-size:1.125rem;color:rgb(var(--ax-sys-color-danger-500))}.ax-scheduler-picker-add-section{display:flex;gap:.5rem;align-items:stretch}.ax-scheduler-picker-date-input{flex:1}.ax-scheduler-picker-chips-container{display:flex;flex-wrap:wrap;gap:.375rem}.ax-scheduler-picker-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.375rem;padding:.75rem .5rem;border:1px dashed rgb(var(--ax-sys-color-border-light-surface));border-radius:var(--ax-sys-border-radius-md);color:rgb(var(--ax-sys-color-on-darker-surface));font-size:.875rem}.ax-scheduler-picker-empty-state .ax-icon{font-size:1.5rem;opacity:.4}\n"] }]
|
|
1651
|
+
}], ctorParameters: () => [], propDecorators: { exclusions: [{ type: i0.Input, args: [{ isSignal: true, alias: "exclusions", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], exclusionsChange: [{ type: i0.Output, args: ["exclusionsChange"] }] } });
|
|
1652
|
+
|
|
1653
|
+
class AXSchedulerPickerInclusionManagerComponent {
|
|
1654
|
+
constructor() {
|
|
1655
|
+
this.inclusions = input(...(ngDevMode ? [undefined, { debugName: "inclusions" }] : []));
|
|
1656
|
+
this.inclusionsChange = output();
|
|
1657
|
+
this.newInclusionDate = signal(null, ...(ngDevMode ? [{ debugName: "newInclusionDate" }] : []));
|
|
1658
|
+
this.inclusionList = signal([], ...(ngDevMode ? [{ debugName: "inclusionList" }] : []));
|
|
1659
|
+
// Sync input with internal list
|
|
1660
|
+
effect(() => {
|
|
1661
|
+
const inclusions = this.inclusions();
|
|
1662
|
+
this.inclusionList.set(inclusions || []);
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
addInclusion() {
|
|
1666
|
+
const date = this.newInclusionDate();
|
|
1667
|
+
if (date) {
|
|
1668
|
+
// Normalize date to midnight
|
|
1669
|
+
const normalized = normalizeDate(date);
|
|
1670
|
+
// Check for duplicates
|
|
1671
|
+
if (!dateExistsInArray(normalized, this.inclusionList())) {
|
|
1672
|
+
const updated = [...this.inclusionList(), normalized];
|
|
1673
|
+
this.inclusionList.set(updated);
|
|
1674
|
+
this.inclusionsChange.emit(updated);
|
|
1675
|
+
}
|
|
1676
|
+
this.newInclusionDate.set(null);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
removeInclusion(date) {
|
|
1680
|
+
const normalized = normalizeDate(date);
|
|
1681
|
+
const updated = this.inclusionList().filter((d) => normalizeDate(d).getTime() !== normalized.getTime());
|
|
1682
|
+
this.inclusionList.set(updated);
|
|
1683
|
+
this.inclusionsChange.emit(updated);
|
|
1684
|
+
}
|
|
1685
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerInclusionManagerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1686
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerInclusionManagerComponent, isStandalone: true, selector: "ax-scheduler-picker-inclusion-manager", inputs: { inclusions: { classPropertyName: "inclusions", publicName: "inclusions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { inclusionsChange: "inclusionsChange" }, host: { classAttribute: "ax-scheduler-picker-inclusion-manager-host" }, ngImport: i0, template: `
|
|
1687
|
+
<div class="ax-scheduler-picker-inclusion-manager">
|
|
1688
|
+
<div class="ax-scheduler-picker-section-header">
|
|
1689
|
+
<label class="ax-scheduler-picker-label">
|
|
1690
|
+
<i class="ax-icon ax-icon-calendar-add"></i>
|
|
1691
|
+
{{ '@acorex:schedulerPicker.labels.includeDates' | translate | async }}
|
|
1692
|
+
</label>
|
|
1693
|
+
@if (inclusionList().length > 0) {
|
|
1694
|
+
<ax-badge [text]="inclusionList().length.toString()"></ax-badge>
|
|
1695
|
+
}
|
|
1696
|
+
</div>
|
|
1697
|
+
|
|
1698
|
+
<div class="ax-scheduler-picker-add-section">
|
|
1699
|
+
<ax-datetime-box
|
|
1700
|
+
class="ax-scheduler-picker-date-input"
|
|
1701
|
+
[value]="newInclusionDate()"
|
|
1702
|
+
mode="date"
|
|
1703
|
+
(valueChange)="newInclusionDate.set($event)"
|
|
1704
|
+
[placeholder]="'@acorex:schedulerPicker.placeholders.selectInclusionDate' | translate | async"
|
|
1705
|
+
/>
|
|
1706
|
+
<ax-button
|
|
1707
|
+
mode="success"
|
|
1708
|
+
(click)="addInclusion()"
|
|
1709
|
+
[disabled]="!newInclusionDate()"
|
|
1710
|
+
[text]="'@acorex:common.actions.add' | translate | async"
|
|
1711
|
+
>
|
|
1712
|
+
<ax-prefix>
|
|
1713
|
+
<i class="ax-icon ax-icon-plus"></i>
|
|
1714
|
+
</ax-prefix>
|
|
1715
|
+
</ax-button>
|
|
1716
|
+
</div>
|
|
1717
|
+
|
|
1718
|
+
@if (inclusionList().length > 0) {
|
|
1719
|
+
<div class="ax-scheduler-picker-chips-container">
|
|
1720
|
+
@for (date of inclusionList(); track date.getTime()) {
|
|
1721
|
+
<ax-chips [text]="date | date: 'mediumDate'" color="success" (click)="removeInclusion(date)">
|
|
1722
|
+
<ax-prefix>
|
|
1723
|
+
<i class="ax-icon ax-icon-calendar"></i>
|
|
1724
|
+
</ax-prefix>
|
|
1725
|
+
<ax-suffix>
|
|
1726
|
+
<i class="ax-icon ax-icon-close"></i>
|
|
1727
|
+
</ax-suffix>
|
|
1728
|
+
</ax-chips>
|
|
1729
|
+
}
|
|
1730
|
+
</div>
|
|
1731
|
+
} @else {
|
|
1732
|
+
<div class="ax-scheduler-picker-empty-state">
|
|
1733
|
+
<i class="ax-icon ax-icon-calendar-check"></i>
|
|
1734
|
+
<span>{{ '@acorex:schedulerPicker.messages.noIncludedDates' | translate | async }}</span>
|
|
1735
|
+
</div>
|
|
1736
|
+
}
|
|
1737
|
+
</div>
|
|
1738
|
+
`, isInline: true, styles: [".ax-scheduler-picker-inclusion-manager{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-section-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:.375rem}.ax-scheduler-picker-label{display:flex;align-items:center;gap:.375rem;color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight)}.ax-scheduler-picker-label .ax-icon{font-size:1.125rem;color:rgb(var(--ax-sys-color-success-500))}.ax-scheduler-picker-add-section{display:flex;gap:.5rem;align-items:stretch}.ax-scheduler-picker-date-input{flex:1}.ax-scheduler-picker-chips-container{display:flex;flex-wrap:wrap;gap:.375rem}.ax-scheduler-picker-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.375rem;padding:.75rem .5rem;border:1px dashed rgb(var(--ax-sys-color-border-light-surface));border-radius:var(--ax-sys-border-radius-md);color:rgb(var(--ax-sys-color-on-darker-surface));font-size:.875rem}.ax-scheduler-picker-empty-state .ax-icon{font-size:1.5rem;opacity:.4}\n"], dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1$1.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: AXBadgeModule }, { kind: "component", type: i2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXChipsModule }, { kind: "component", type: i3.AXChipsComponent, selector: "ax-chips", inputs: ["tabIndex", "color", "look", "text"], outputs: ["textChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: AXDateTimeBoxComponent, selector: "ax-datetime-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "depth", "id", "type", "look", "holidayDates", "allowTyping", "picker", "calendar", "weekend", "weekdays", "format"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "onOpened", "onClosed", "readonlyChange", "disabledChange", "formatChange"] }, { 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: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1739
|
+
}
|
|
1740
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerInclusionManagerComponent, decorators: [{
|
|
1741
|
+
type: Component,
|
|
1742
|
+
args: [{ selector: 'ax-scheduler-picker-inclusion-manager', template: `
|
|
1743
|
+
<div class="ax-scheduler-picker-inclusion-manager">
|
|
1744
|
+
<div class="ax-scheduler-picker-section-header">
|
|
1745
|
+
<label class="ax-scheduler-picker-label">
|
|
1746
|
+
<i class="ax-icon ax-icon-calendar-add"></i>
|
|
1747
|
+
{{ '@acorex:schedulerPicker.labels.includeDates' | translate | async }}
|
|
1748
|
+
</label>
|
|
1749
|
+
@if (inclusionList().length > 0) {
|
|
1750
|
+
<ax-badge [text]="inclusionList().length.toString()"></ax-badge>
|
|
1751
|
+
}
|
|
1752
|
+
</div>
|
|
1753
|
+
|
|
1754
|
+
<div class="ax-scheduler-picker-add-section">
|
|
1755
|
+
<ax-datetime-box
|
|
1756
|
+
class="ax-scheduler-picker-date-input"
|
|
1757
|
+
[value]="newInclusionDate()"
|
|
1758
|
+
mode="date"
|
|
1759
|
+
(valueChange)="newInclusionDate.set($event)"
|
|
1760
|
+
[placeholder]="'@acorex:schedulerPicker.placeholders.selectInclusionDate' | translate | async"
|
|
1761
|
+
/>
|
|
1762
|
+
<ax-button
|
|
1763
|
+
mode="success"
|
|
1764
|
+
(click)="addInclusion()"
|
|
1765
|
+
[disabled]="!newInclusionDate()"
|
|
1766
|
+
[text]="'@acorex:common.actions.add' | translate | async"
|
|
1767
|
+
>
|
|
1768
|
+
<ax-prefix>
|
|
1769
|
+
<i class="ax-icon ax-icon-plus"></i>
|
|
1770
|
+
</ax-prefix>
|
|
1771
|
+
</ax-button>
|
|
1772
|
+
</div>
|
|
1773
|
+
|
|
1774
|
+
@if (inclusionList().length > 0) {
|
|
1775
|
+
<div class="ax-scheduler-picker-chips-container">
|
|
1776
|
+
@for (date of inclusionList(); track date.getTime()) {
|
|
1777
|
+
<ax-chips [text]="date | date: 'mediumDate'" color="success" (click)="removeInclusion(date)">
|
|
1778
|
+
<ax-prefix>
|
|
1779
|
+
<i class="ax-icon ax-icon-calendar"></i>
|
|
1780
|
+
</ax-prefix>
|
|
1781
|
+
<ax-suffix>
|
|
1782
|
+
<i class="ax-icon ax-icon-close"></i>
|
|
1783
|
+
</ax-suffix>
|
|
1784
|
+
</ax-chips>
|
|
1785
|
+
}
|
|
1786
|
+
</div>
|
|
1787
|
+
} @else {
|
|
1788
|
+
<div class="ax-scheduler-picker-empty-state">
|
|
1789
|
+
<i class="ax-icon ax-icon-calendar-check"></i>
|
|
1790
|
+
<span>{{ '@acorex:schedulerPicker.messages.noIncludedDates' | translate | async }}</span>
|
|
1791
|
+
</div>
|
|
1792
|
+
}
|
|
1793
|
+
</div>
|
|
1794
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
1795
|
+
AXDecoratorModule,
|
|
1796
|
+
AXBadgeModule,
|
|
1797
|
+
AXChipsModule,
|
|
1798
|
+
FormsModule,
|
|
1799
|
+
AXDateTimeBoxComponent,
|
|
1800
|
+
AXButtonComponent,
|
|
1801
|
+
AXTranslatorPipe,
|
|
1802
|
+
AsyncPipe,
|
|
1803
|
+
DatePipe,
|
|
1804
|
+
], host: {
|
|
1805
|
+
class: 'ax-scheduler-picker-inclusion-manager-host',
|
|
1806
|
+
}, styles: [".ax-scheduler-picker-inclusion-manager{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-section-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:.375rem}.ax-scheduler-picker-label{display:flex;align-items:center;gap:.375rem;color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight)}.ax-scheduler-picker-label .ax-icon{font-size:1.125rem;color:rgb(var(--ax-sys-color-success-500))}.ax-scheduler-picker-add-section{display:flex;gap:.5rem;align-items:stretch}.ax-scheduler-picker-date-input{flex:1}.ax-scheduler-picker-chips-container{display:flex;flex-wrap:wrap;gap:.375rem}.ax-scheduler-picker-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.375rem;padding:.75rem .5rem;border:1px dashed rgb(var(--ax-sys-color-border-light-surface));border-radius:var(--ax-sys-border-radius-md);color:rgb(var(--ax-sys-color-on-darker-surface));font-size:.875rem}.ax-scheduler-picker-empty-state .ax-icon{font-size:1.5rem;opacity:.4}\n"] }]
|
|
1807
|
+
}], ctorParameters: () => [], propDecorators: { inclusions: [{ type: i0.Input, args: [{ isSignal: true, alias: "inclusions", required: false }] }], inclusionsChange: [{ type: i0.Output, args: ["inclusionsChange"] }] } });
|
|
1808
|
+
|
|
1809
|
+
/**
|
|
1810
|
+
* A powerful, fully customizable scheduler picker component for creating recurrence patterns
|
|
1811
|
+
*
|
|
1812
|
+
* ## Features
|
|
1813
|
+
* - Supports 5 modes: hourly, daily, weekly, monthly, and yearly
|
|
1814
|
+
* - Flexible start and end conditions
|
|
1815
|
+
* - Date exclusions and inclusions
|
|
1816
|
+
* - Natural language summary generation
|
|
1817
|
+
* - Export to Cron and RRule (iCalendar) formats
|
|
1818
|
+
* - Full i18n support
|
|
1819
|
+
* - Type-safe configuration
|
|
1820
|
+
*
|
|
1821
|
+
* ## Basic Usage
|
|
1822
|
+
* ```typescript
|
|
1823
|
+
* <ax-scheduler-picker
|
|
1824
|
+
* [config]="{ mode: 'daily', showEndConditions: true }"
|
|
1825
|
+
* [(value)]="pattern"
|
|
1826
|
+
* (summaryChange)="onSummaryChange($event)"
|
|
1827
|
+
* />
|
|
1828
|
+
* ```
|
|
1829
|
+
*
|
|
1830
|
+
* ## Public API
|
|
1831
|
+
* - `validatePattern()` - Manually trigger validation
|
|
1832
|
+
* - `getPreview(count)` - Get next N occurrences
|
|
1833
|
+
* - `toCron()` - Convert to cron expression
|
|
1834
|
+
* - `toRRule()` - Convert to RRule string
|
|
1835
|
+
* - `reset()` - Reset to default pattern
|
|
1836
|
+
* - `clear()` - Clear all data
|
|
1837
|
+
* - `validationErrors` - Signal containing current validation errors
|
|
1838
|
+
*
|
|
1839
|
+
* @category Components
|
|
1840
|
+
*/
|
|
1841
|
+
class AXSchedulerPickerComponent extends MXValueComponent {
|
|
1842
|
+
internalValueChanged(value) {
|
|
1843
|
+
if (value) {
|
|
1844
|
+
this.pattern.set(value);
|
|
1845
|
+
}
|
|
1846
|
+
else {
|
|
1847
|
+
this.initializeDefaultValue();
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
constructor() {
|
|
1851
|
+
super();
|
|
1852
|
+
/**
|
|
1853
|
+
* Settings for the scheduler picker
|
|
1854
|
+
* Controls which options are visible and behavior
|
|
1855
|
+
*/
|
|
1856
|
+
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
1857
|
+
/**
|
|
1858
|
+
* Emits when the human-readable summary changes
|
|
1859
|
+
*/
|
|
1860
|
+
this.summaryChange = output();
|
|
1861
|
+
this.service = inject(AXSchedulerPickerService);
|
|
1862
|
+
/**
|
|
1863
|
+
* Internal pattern value
|
|
1864
|
+
*/
|
|
1865
|
+
this.pattern = signal(null, ...(ngDevMode ? [{ debugName: "pattern" }] : []));
|
|
1866
|
+
/**
|
|
1867
|
+
* Current mode derived from config
|
|
1868
|
+
*/
|
|
1869
|
+
this.mode = computed(() => this.config().mode, ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
1870
|
+
/**
|
|
1871
|
+
* Effect run counter to prevent stale async updates
|
|
1872
|
+
*/
|
|
1873
|
+
this.effectRunId = 0;
|
|
1874
|
+
/**
|
|
1875
|
+
* Merged configuration with defaults
|
|
1876
|
+
*/
|
|
1877
|
+
this.mergedConfig = computed(() => {
|
|
1878
|
+
const defaultConfig = getDefaultSchedulerPickerConfig(this.config().mode);
|
|
1879
|
+
return {
|
|
1880
|
+
...defaultConfig,
|
|
1881
|
+
...this.config(),
|
|
1882
|
+
options: {
|
|
1883
|
+
...defaultConfig.options,
|
|
1884
|
+
...this.config().options,
|
|
1885
|
+
},
|
|
1886
|
+
};
|
|
1887
|
+
}, ...(ngDevMode ? [{ debugName: "mergedConfig" }] : []));
|
|
1888
|
+
/**
|
|
1889
|
+
* Validation errors (public for external access)
|
|
1890
|
+
*/
|
|
1891
|
+
this.validationErrors = signal([], ...(ngDevMode ? [{ debugName: "validationErrors" }] : []));
|
|
1892
|
+
/**
|
|
1893
|
+
* Human-readable summary of the pattern
|
|
1894
|
+
*/
|
|
1895
|
+
this.summary = signal('', ...(ngDevMode ? [{ debugName: "summary" }] : []));
|
|
1896
|
+
// Effect to update summary when pattern changes
|
|
1897
|
+
effect(() => {
|
|
1898
|
+
const currentPattern = this.pattern();
|
|
1899
|
+
if (currentPattern) {
|
|
1900
|
+
const runId = ++this.effectRunId;
|
|
1901
|
+
this.service.toNaturalLanguage(currentPattern, this.mergedConfig().locale).then((result) => {
|
|
1902
|
+
// Only update if this is still the latest run
|
|
1903
|
+
if (runId === this.effectRunId) {
|
|
1904
|
+
this.summary.set(result);
|
|
1905
|
+
this.summaryChange.emit(result);
|
|
1906
|
+
}
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1909
|
+
else {
|
|
1910
|
+
this.summary.set('');
|
|
1911
|
+
this.summaryChange.emit('');
|
|
1912
|
+
}
|
|
1913
|
+
});
|
|
1914
|
+
}
|
|
1915
|
+
/**
|
|
1916
|
+
* Initialize with default value based on mode
|
|
1917
|
+
*/
|
|
1918
|
+
initializeDefaultValue() {
|
|
1919
|
+
if (!this.value) {
|
|
1920
|
+
const defaultValue = {
|
|
1921
|
+
mode: this.config().mode,
|
|
1922
|
+
interval: this.config().defaultInterval || 1,
|
|
1923
|
+
startCondition: {
|
|
1924
|
+
type: 'now',
|
|
1925
|
+
startDate: new Date(),
|
|
1926
|
+
},
|
|
1927
|
+
recurrence: {},
|
|
1928
|
+
endCondition: {
|
|
1929
|
+
type: 'never',
|
|
1930
|
+
},
|
|
1931
|
+
};
|
|
1932
|
+
this.value = defaultValue;
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
/**
|
|
1936
|
+
* Update pattern value
|
|
1937
|
+
*/
|
|
1938
|
+
updatePattern(updates) {
|
|
1939
|
+
const currentPattern = this.pattern();
|
|
1940
|
+
if (currentPattern) {
|
|
1941
|
+
const newPattern = this.mergePatternUpdates(currentPattern, updates);
|
|
1942
|
+
this.pattern.set(newPattern);
|
|
1943
|
+
this.value = newPattern;
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
/**
|
|
1947
|
+
* Deep merge pattern updates with current pattern
|
|
1948
|
+
* Preserves nested object properties that aren't being updated
|
|
1949
|
+
*/
|
|
1950
|
+
mergePatternUpdates(current, updates) {
|
|
1951
|
+
return {
|
|
1952
|
+
...current,
|
|
1953
|
+
...updates,
|
|
1954
|
+
// Deep merge recurrence to preserve existing properties
|
|
1955
|
+
recurrence: updates.recurrence
|
|
1956
|
+
? {
|
|
1957
|
+
...current.recurrence,
|
|
1958
|
+
...updates.recurrence,
|
|
1959
|
+
}
|
|
1960
|
+
: current.recurrence,
|
|
1961
|
+
// Deep merge startCondition to preserve existing properties
|
|
1962
|
+
startCondition: updates.startCondition
|
|
1963
|
+
? {
|
|
1964
|
+
...current.startCondition,
|
|
1965
|
+
...updates.startCondition,
|
|
1966
|
+
}
|
|
1967
|
+
: current.startCondition,
|
|
1968
|
+
// Deep merge endCondition to preserve existing properties
|
|
1969
|
+
endCondition: updates.endCondition
|
|
1970
|
+
? {
|
|
1971
|
+
...current.endCondition,
|
|
1972
|
+
...updates.endCondition,
|
|
1973
|
+
}
|
|
1974
|
+
: current.endCondition,
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
/**
|
|
1978
|
+
* Manually validate the current pattern
|
|
1979
|
+
*
|
|
1980
|
+
* Validates the pattern against configured rules and constraints.
|
|
1981
|
+
* Updates the `validationErrors` signal and component state.
|
|
1982
|
+
*
|
|
1983
|
+
* @returns Promise resolving to `true` if pattern is valid, `false` otherwise
|
|
1984
|
+
*
|
|
1985
|
+
* @example
|
|
1986
|
+
* ```typescript
|
|
1987
|
+
* const isValid = await schedulerPicker.validatePattern();
|
|
1988
|
+
* if (!isValid) {
|
|
1989
|
+
* const errors = schedulerPicker.validationErrors();
|
|
1990
|
+
* console.log('Validation errors:', errors);
|
|
1991
|
+
* }
|
|
1992
|
+
* ```
|
|
1993
|
+
*/
|
|
1994
|
+
async validatePattern() {
|
|
1995
|
+
const currentPattern = this.pattern();
|
|
1996
|
+
if (!currentPattern) {
|
|
1997
|
+
return false;
|
|
1998
|
+
}
|
|
1999
|
+
const errors = await this.service.validatePattern(currentPattern, this.mergedConfig());
|
|
2000
|
+
const errorMessages = errors.map((e) => e.message);
|
|
2001
|
+
this.validationErrors.set(errorMessages);
|
|
2002
|
+
if (errors.length > 0) {
|
|
2003
|
+
this.setState('error');
|
|
2004
|
+
return false;
|
|
2005
|
+
}
|
|
2006
|
+
else {
|
|
2007
|
+
this.setState('clear');
|
|
2008
|
+
return true;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* Get preview of next N occurrences based on the current pattern
|
|
2013
|
+
*
|
|
2014
|
+
* @param count - Number of occurrences to return (default: 10)
|
|
2015
|
+
* @param startFrom - Optional starting date (default: now)
|
|
2016
|
+
* @returns Promise resolving to array of dates representing next occurrences
|
|
2017
|
+
* @returns Empty array if pattern is invalid or not set
|
|
2018
|
+
*
|
|
2019
|
+
* @example
|
|
2020
|
+
* ```typescript
|
|
2021
|
+
* const dates = await schedulerPicker.getPreview(5);
|
|
2022
|
+
* console.log('Next 5 occurrences:', dates);
|
|
2023
|
+
* ```
|
|
2024
|
+
*/
|
|
2025
|
+
async getPreview(count = 10, startFrom) {
|
|
2026
|
+
const currentPattern = this.pattern();
|
|
2027
|
+
if (!currentPattern) {
|
|
2028
|
+
return [];
|
|
2029
|
+
}
|
|
2030
|
+
return await this.service.calculateOccurrences(currentPattern, count, startFrom);
|
|
2031
|
+
}
|
|
2032
|
+
/**
|
|
2033
|
+
* Convert current pattern to cron expression
|
|
2034
|
+
*
|
|
2035
|
+
* @returns Promise resolving to cron expression string
|
|
2036
|
+
* @returns Empty string if pattern is not set or invalid
|
|
2037
|
+
*
|
|
2038
|
+
* @example
|
|
2039
|
+
* ```typescript
|
|
2040
|
+
* const cron = await schedulerPicker.toCron();
|
|
2041
|
+
* console.log('Cron expression:', cron); // "0 9 * * 1-5"
|
|
2042
|
+
* ```
|
|
2043
|
+
*/
|
|
2044
|
+
async toCron() {
|
|
2045
|
+
const currentPattern = this.pattern();
|
|
2046
|
+
if (!currentPattern) {
|
|
2047
|
+
return '';
|
|
2048
|
+
}
|
|
2049
|
+
return await this.service.toCronExpression(currentPattern);
|
|
2050
|
+
}
|
|
2051
|
+
/**
|
|
2052
|
+
* Convert current pattern to RRule string (iCalendar format)
|
|
2053
|
+
*
|
|
2054
|
+
* @returns Promise resolving to RRule string
|
|
2055
|
+
* @returns Empty string if pattern is not set or invalid
|
|
2056
|
+
*
|
|
2057
|
+
* @example
|
|
2058
|
+
* ```typescript
|
|
2059
|
+
* const rrule = await schedulerPicker.toRRule();
|
|
2060
|
+
* console.log('RRule:', rrule); // "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR"
|
|
2061
|
+
* ```
|
|
2062
|
+
*/
|
|
2063
|
+
async toRRule() {
|
|
2064
|
+
const currentPattern = this.pattern();
|
|
2065
|
+
if (!currentPattern) {
|
|
2066
|
+
return '';
|
|
2067
|
+
}
|
|
2068
|
+
return await this.service.toRRule(currentPattern);
|
|
2069
|
+
}
|
|
2070
|
+
/**
|
|
2071
|
+
* Reset pattern to default value based on current mode
|
|
2072
|
+
* Clears current pattern and re-initializes with mode-specific defaults
|
|
2073
|
+
*
|
|
2074
|
+
* @param e - Optional event parameter (inherited from base class)
|
|
2075
|
+
*
|
|
2076
|
+
* @example
|
|
2077
|
+
* ```typescript
|
|
2078
|
+
* schedulerPicker.reset();
|
|
2079
|
+
* // Pattern is now reset to default for the configured mode
|
|
2080
|
+
* ```
|
|
2081
|
+
*/
|
|
2082
|
+
reset(e = false) {
|
|
2083
|
+
super.reset(e);
|
|
2084
|
+
this.pattern.set(null);
|
|
2085
|
+
this.initializeDefaultValue();
|
|
2086
|
+
}
|
|
2087
|
+
/**
|
|
2088
|
+
* Clear pattern completely
|
|
2089
|
+
* Removes all pattern data, summary, and validation errors
|
|
2090
|
+
* Sets component state to 'clear'
|
|
2091
|
+
*
|
|
2092
|
+
* @example
|
|
2093
|
+
* ```typescript
|
|
2094
|
+
* schedulerPicker.clear();
|
|
2095
|
+
* // All data cleared, component is now empty
|
|
2096
|
+
* ```
|
|
2097
|
+
*/
|
|
2098
|
+
clear() {
|
|
2099
|
+
this.pattern.set(null);
|
|
2100
|
+
this.value = null;
|
|
2101
|
+
this.summary.set('');
|
|
2102
|
+
this.validationErrors.set([]);
|
|
2103
|
+
this.setState('clear');
|
|
2104
|
+
}
|
|
2105
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2106
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerComponent, isStandalone: true, selector: "ax-scheduler-picker", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: false, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: false, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: false, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: false, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: false, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChange: "valueChange", stateChange: "stateChange", onValueChanged: "onValueChanged", onBlur: "onBlur", onFocus: "onFocus", summaryChange: "summaryChange" }, providers: [
|
|
2107
|
+
{ provide: AXComponent, useExisting: AXSchedulerPickerComponent },
|
|
2108
|
+
{ provide: AXFocusableComponent, useExisting: AXSchedulerPickerComponent },
|
|
2109
|
+
{ provide: AXValuableComponent, useExisting: AXSchedulerPickerComponent },
|
|
2110
|
+
{
|
|
2111
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2112
|
+
useExisting: forwardRef(() => AXSchedulerPickerComponent),
|
|
2113
|
+
multi: true,
|
|
2114
|
+
},
|
|
2115
|
+
], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-scheduler-picker\" [class.ax-disabled]=\"disabled\" [class.ax-readonly]=\"readonly\">\n <!-- Mode-specific panel -->\n <div class=\"ax-scheduler-picker-panel\">\n @switch (mode()) {\n @case ('hourly') {\n <ax-scheduler-picker-hourly-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n @case ('daily') {\n <ax-scheduler-picker-daily-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n @case ('weekly') {\n <ax-scheduler-picker-weekly-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n @case ('monthly') {\n <ax-scheduler-picker-monthly-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n @case ('yearly') {\n <ax-scheduler-picker-yearly-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n }\n </div>\n\n <!-- Start condition -->\n @if (mergedConfig().showStartCondition && pattern()) {\n <div class=\"ax-scheduler-picker-start-conditions\">\n <ax-scheduler-picker-start-condition-selector\n [startCondition]=\"pattern()!.startCondition\"\n [config]=\"mergedConfig()\"\n (startConditionChange)=\"updatePattern({ startCondition: $event })\"\n />\n </div>\n }\n\n <!-- End conditions -->\n @if (mergedConfig().showEndConditions && pattern()) {\n <div class=\"ax-scheduler-picker-end-conditions\">\n <ax-scheduler-picker-end-condition-selector\n [endCondition]=\"pattern()!.endCondition\"\n [config]=\"mergedConfig()\"\n (endConditionChange)=\"updatePattern({ endCondition: $event })\"\n />\n </div>\n }\n\n <!-- Exclusions -->\n @if (mergedConfig().showExclusions && pattern()) {\n <div class=\"ax-scheduler-picker-exclusions\">\n <ax-scheduler-picker-exclusion-manager\n [exclusions]=\"pattern()!.exclusions || []\"\n [config]=\"mergedConfig()\"\n (exclusionsChange)=\"updatePattern({ exclusions: $event })\"\n />\n </div>\n }\n\n <!-- Inclusions -->\n @if (mergedConfig().showInclusions && pattern()) {\n <div class=\"ax-scheduler-picker-inclusions\">\n <ax-scheduler-picker-inclusion-manager\n [inclusions]=\"pattern()!.inclusions || []\"\n (inclusionsChange)=\"updatePattern({ inclusions: $event })\"\n />\n </div>\n }\n</div>\n", styles: [":root{--ax-comp-scheduler-picker-border: 1px solid rgb(var(--ax-sys-color-border-lighter-surface));--ax-comp-scheduler-picker-border-radius: var(--ax-sys-border-radius-md);--ax-comp-scheduler-picker-padding: .5rem;--ax-comp-scheduler-picker-gap: .5rem;--ax-comp-scheduler-picker-label-color: rgb(var(--ax-sys-color-on-lighter-surface));--ax-comp-scheduler-picker-label-font-size: .875rem;--ax-comp-scheduler-picker-label-font-weight: 500;--ax-comp-scheduler-picker-summary-color: rgb(var(--ax-sys-color-on-darker-surface));--ax-comp-scheduler-picker-summary-padding: .375rem .5rem;--ax-comp-scheduler-picker-error-color: rgb(var(--ax-sys-color-danger-500));--ax-comp-scheduler-picker-error-padding: .375rem .5rem}.ax-scheduler-picker{display:flex;flex-direction:column;gap:var(--ax-comp-scheduler-picker-gap);padding:var(--ax-comp-scheduler-picker-padding)}.ax-scheduler-picker.ax-disabled{opacity:.6;pointer-events:none}.ax-scheduler-picker.ax-readonly{pointer-events:none}.ax-scheduler-picker-summary{display:flex;align-items:center;gap:.375rem;padding:var(--ax-comp-scheduler-picker-summary-padding);color:var(--ax-comp-scheduler-picker-summary-color);font-size:.875rem}.ax-scheduler-picker-summary .ax-scheduler-picker-summary-label{font-weight:var(--ax-comp-scheduler-picker-label-font-weight)}.ax-scheduler-picker-errors{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-error{padding:var(--ax-comp-scheduler-picker-error-padding);color:var(--ax-comp-scheduler-picker-error-color);font-size:.875rem}\n"], dependencies: [{ kind: "component", type: AXSchedulerPickerHourlyPanelComponent, selector: "ax-scheduler-picker-hourly-panel", inputs: ["pattern", "config"], outputs: ["patternChange"] }, { kind: "component", type: AXSchedulerPickerDailyPanelComponent, selector: "ax-scheduler-picker-daily-panel", inputs: ["pattern", "config"], outputs: ["patternChange"] }, { kind: "component", type: AXSchedulerPickerWeeklyPanelComponent, selector: "ax-scheduler-picker-weekly-panel", inputs: ["pattern", "config"], outputs: ["patternChange"] }, { kind: "component", type: AXSchedulerPickerMonthlyPanelComponent, selector: "ax-scheduler-picker-monthly-panel", inputs: ["pattern", "config"], outputs: ["patternChange"] }, { kind: "component", type: AXSchedulerPickerYearlyPanelComponent, selector: "ax-scheduler-picker-yearly-panel", inputs: ["pattern", "config"], outputs: ["patternChange"] }, { kind: "component", type: AXSchedulerPickerStartConditionSelectorComponent, selector: "ax-scheduler-picker-start-condition-selector", inputs: ["startCondition", "config"], outputs: ["startConditionChange"] }, { kind: "component", type: AXSchedulerPickerEndConditionSelectorComponent, selector: "ax-scheduler-picker-end-condition-selector", inputs: ["endCondition", "config"], outputs: ["endConditionChange"] }, { kind: "component", type: AXSchedulerPickerExclusionManagerComponent, selector: "ax-scheduler-picker-exclusion-manager", inputs: ["exclusions", "config"], outputs: ["exclusionsChange"] }, { kind: "component", type: AXSchedulerPickerInclusionManagerComponent, selector: "ax-scheduler-picker-inclusion-manager", inputs: ["inclusions"], outputs: ["inclusionsChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2116
|
+
}
|
|
2117
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerComponent, decorators: [{
|
|
2118
|
+
type: Component,
|
|
2119
|
+
args: [{ selector: 'ax-scheduler-picker', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, inputs: ['disabled', 'readonly', 'tabIndex', 'value', 'state', 'name', 'id'], outputs: ['valueChange', 'stateChange', 'onValueChanged', 'onBlur', 'onFocus'], providers: [
|
|
2120
|
+
{ provide: AXComponent, useExisting: AXSchedulerPickerComponent },
|
|
2121
|
+
{ provide: AXFocusableComponent, useExisting: AXSchedulerPickerComponent },
|
|
2122
|
+
{ provide: AXValuableComponent, useExisting: AXSchedulerPickerComponent },
|
|
2123
|
+
{
|
|
2124
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2125
|
+
useExisting: forwardRef(() => AXSchedulerPickerComponent),
|
|
2126
|
+
multi: true,
|
|
2127
|
+
},
|
|
2128
|
+
], imports: [
|
|
2129
|
+
AXSchedulerPickerHourlyPanelComponent,
|
|
2130
|
+
AXSchedulerPickerDailyPanelComponent,
|
|
2131
|
+
AXSchedulerPickerWeeklyPanelComponent,
|
|
2132
|
+
AXSchedulerPickerMonthlyPanelComponent,
|
|
2133
|
+
AXSchedulerPickerYearlyPanelComponent,
|
|
2134
|
+
AXSchedulerPickerStartConditionSelectorComponent,
|
|
2135
|
+
AXSchedulerPickerEndConditionSelectorComponent,
|
|
2136
|
+
AXSchedulerPickerExclusionManagerComponent,
|
|
2137
|
+
AXSchedulerPickerInclusionManagerComponent,
|
|
2138
|
+
], template: "<div class=\"ax-scheduler-picker\" [class.ax-disabled]=\"disabled\" [class.ax-readonly]=\"readonly\">\n <!-- Mode-specific panel -->\n <div class=\"ax-scheduler-picker-panel\">\n @switch (mode()) {\n @case ('hourly') {\n <ax-scheduler-picker-hourly-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n @case ('daily') {\n <ax-scheduler-picker-daily-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n @case ('weekly') {\n <ax-scheduler-picker-weekly-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n @case ('monthly') {\n <ax-scheduler-picker-monthly-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n @case ('yearly') {\n <ax-scheduler-picker-yearly-panel\n [pattern]=\"pattern()\"\n [config]=\"$any(mergedConfig())\"\n (patternChange)=\"updatePattern($event)\"\n />\n }\n }\n </div>\n\n <!-- Start condition -->\n @if (mergedConfig().showStartCondition && pattern()) {\n <div class=\"ax-scheduler-picker-start-conditions\">\n <ax-scheduler-picker-start-condition-selector\n [startCondition]=\"pattern()!.startCondition\"\n [config]=\"mergedConfig()\"\n (startConditionChange)=\"updatePattern({ startCondition: $event })\"\n />\n </div>\n }\n\n <!-- End conditions -->\n @if (mergedConfig().showEndConditions && pattern()) {\n <div class=\"ax-scheduler-picker-end-conditions\">\n <ax-scheduler-picker-end-condition-selector\n [endCondition]=\"pattern()!.endCondition\"\n [config]=\"mergedConfig()\"\n (endConditionChange)=\"updatePattern({ endCondition: $event })\"\n />\n </div>\n }\n\n <!-- Exclusions -->\n @if (mergedConfig().showExclusions && pattern()) {\n <div class=\"ax-scheduler-picker-exclusions\">\n <ax-scheduler-picker-exclusion-manager\n [exclusions]=\"pattern()!.exclusions || []\"\n [config]=\"mergedConfig()\"\n (exclusionsChange)=\"updatePattern({ exclusions: $event })\"\n />\n </div>\n }\n\n <!-- Inclusions -->\n @if (mergedConfig().showInclusions && pattern()) {\n <div class=\"ax-scheduler-picker-inclusions\">\n <ax-scheduler-picker-inclusion-manager\n [inclusions]=\"pattern()!.inclusions || []\"\n (inclusionsChange)=\"updatePattern({ inclusions: $event })\"\n />\n </div>\n }\n</div>\n", styles: [":root{--ax-comp-scheduler-picker-border: 1px solid rgb(var(--ax-sys-color-border-lighter-surface));--ax-comp-scheduler-picker-border-radius: var(--ax-sys-border-radius-md);--ax-comp-scheduler-picker-padding: .5rem;--ax-comp-scheduler-picker-gap: .5rem;--ax-comp-scheduler-picker-label-color: rgb(var(--ax-sys-color-on-lighter-surface));--ax-comp-scheduler-picker-label-font-size: .875rem;--ax-comp-scheduler-picker-label-font-weight: 500;--ax-comp-scheduler-picker-summary-color: rgb(var(--ax-sys-color-on-darker-surface));--ax-comp-scheduler-picker-summary-padding: .375rem .5rem;--ax-comp-scheduler-picker-error-color: rgb(var(--ax-sys-color-danger-500));--ax-comp-scheduler-picker-error-padding: .375rem .5rem}.ax-scheduler-picker{display:flex;flex-direction:column;gap:var(--ax-comp-scheduler-picker-gap);padding:var(--ax-comp-scheduler-picker-padding)}.ax-scheduler-picker.ax-disabled{opacity:.6;pointer-events:none}.ax-scheduler-picker.ax-readonly{pointer-events:none}.ax-scheduler-picker-summary{display:flex;align-items:center;gap:.375rem;padding:var(--ax-comp-scheduler-picker-summary-padding);color:var(--ax-comp-scheduler-picker-summary-color);font-size:.875rem}.ax-scheduler-picker-summary .ax-scheduler-picker-summary-label{font-weight:var(--ax-comp-scheduler-picker-label-font-weight)}.ax-scheduler-picker-errors{display:flex;flex-direction:column;gap:.375rem}.ax-scheduler-picker-error{padding:var(--ax-comp-scheduler-picker-error-padding);color:var(--ax-comp-scheduler-picker-error-color);font-size:.875rem}\n"] }]
|
|
2139
|
+
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], summaryChange: [{ type: i0.Output, args: ["summaryChange"] }] } });
|
|
2140
|
+
|
|
2141
|
+
class AXSchedulerPickerTimeSelectorComponent {
|
|
2142
|
+
constructor() {
|
|
2143
|
+
this.time = input(...(ngDevMode ? [undefined, { debugName: "time" }] : []));
|
|
2144
|
+
this.timeChange = output();
|
|
2145
|
+
}
|
|
2146
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerTimeSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2147
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: AXSchedulerPickerTimeSelectorComponent, isStandalone: true, selector: "ax-scheduler-picker-time-selector", inputs: { time: { classPropertyName: "time", publicName: "time", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { timeChange: "timeChange" }, ngImport: i0, template: `
|
|
2148
|
+
<div class="ax-scheduler-picker-time-selector">
|
|
2149
|
+
<label class="ax-scheduler-picker-label">
|
|
2150
|
+
{{ '@acorex:schedulerPicker.labels.time' | translate | async }}
|
|
2151
|
+
</label>
|
|
2152
|
+
<ax-datetime-box
|
|
2153
|
+
[value]="time() || '09:00'"
|
|
2154
|
+
[picker]="'time'"
|
|
2155
|
+
(valueChange)="timeChange.emit($event)"
|
|
2156
|
+
/>
|
|
2157
|
+
</div>
|
|
2158
|
+
`, isInline: true, styles: [".ax-scheduler-picker-time-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: AXDateTimeBoxComponent, selector: "ax-datetime-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "depth", "id", "type", "look", "holidayDates", "allowTyping", "picker", "calendar", "weekend", "weekdays", "format"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "onOpened", "onClosed", "readonlyChange", "disabledChange", "formatChange"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2159
|
+
}
|
|
2160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerTimeSelectorComponent, decorators: [{
|
|
2161
|
+
type: Component,
|
|
2162
|
+
args: [{ selector: 'ax-scheduler-picker-time-selector', template: `
|
|
2163
|
+
<div class="ax-scheduler-picker-time-selector">
|
|
2164
|
+
<label class="ax-scheduler-picker-label">
|
|
2165
|
+
{{ '@acorex:schedulerPicker.labels.time' | translate | async }}
|
|
2166
|
+
</label>
|
|
2167
|
+
<ax-datetime-box
|
|
2168
|
+
[value]="time() || '09:00'"
|
|
2169
|
+
[picker]="'time'"
|
|
2170
|
+
(valueChange)="timeChange.emit($event)"
|
|
2171
|
+
/>
|
|
2172
|
+
</div>
|
|
2173
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [FormsModule, AXDateTimeBoxComponent, AXTranslatorPipe, AsyncPipe], styles: [".ax-scheduler-picker-time-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight);margin:0}\n"] }]
|
|
2174
|
+
}], propDecorators: { time: [{ type: i0.Input, args: [{ isSignal: true, alias: "time", required: false }] }], timeChange: [{ type: i0.Output, args: ["timeChange"] }] } });
|
|
2175
|
+
|
|
2176
|
+
class AXSchedulerPickerTimezoneSelectorComponent {
|
|
2177
|
+
constructor() {
|
|
2178
|
+
/**
|
|
2179
|
+
* Current timezone value
|
|
2180
|
+
*/
|
|
2181
|
+
this.timezone = input(...(ngDevMode ? [undefined, { debugName: "timezone" }] : []));
|
|
2182
|
+
/**
|
|
2183
|
+
* Emits when timezone selection changes
|
|
2184
|
+
*/
|
|
2185
|
+
this.timezoneChange = output();
|
|
2186
|
+
this.timezones = [
|
|
2187
|
+
{ value: 'UTC', text: 'UTC' },
|
|
2188
|
+
{ value: 'America/New_York', text: 'Eastern Time (ET)' },
|
|
2189
|
+
{ value: 'America/Chicago', text: 'Central Time (CT)' },
|
|
2190
|
+
{ value: 'America/Denver', text: 'Mountain Time (MT)' },
|
|
2191
|
+
{ value: 'America/Los_Angeles', text: 'Pacific Time (PT)' },
|
|
2192
|
+
{ value: 'Europe/London', text: 'London (GMT)' },
|
|
2193
|
+
{ value: 'Europe/Paris', text: 'Paris (CET)' },
|
|
2194
|
+
{ value: 'Asia/Dubai', text: 'Dubai (GST)' },
|
|
2195
|
+
{ value: 'Asia/Tehran', text: 'Tehran (IRST)' },
|
|
2196
|
+
{ value: 'Asia/Tokyo', text: 'Tokyo (JST)' },
|
|
2197
|
+
{ value: 'Australia/Sydney', text: 'Sydney (AEDT)' },
|
|
2198
|
+
];
|
|
2199
|
+
}
|
|
2200
|
+
/**
|
|
2201
|
+
* Handle timezone selection change
|
|
2202
|
+
*/
|
|
2203
|
+
onTimezoneChange(event) {
|
|
2204
|
+
this.timezoneChange.emit(event.value);
|
|
2205
|
+
}
|
|
2206
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerTimezoneSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2207
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: AXSchedulerPickerTimezoneSelectorComponent, isStandalone: true, selector: "ax-scheduler-picker-timezone-selector", inputs: { timezone: { classPropertyName: "timezone", publicName: "timezone", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { timezoneChange: "timezoneChange" }, ngImport: i0, template: `
|
|
2208
|
+
<div class="ax-scheduler-picker-timezone-selector">
|
|
2209
|
+
<label class="ax-scheduler-picker-label">
|
|
2210
|
+
{{ '@acorex:schedulerPicker.labels.timezone' | translate | async }}
|
|
2211
|
+
</label>
|
|
2212
|
+
<ax-select-box
|
|
2213
|
+
[value]="timezone() || 'UTC'"
|
|
2214
|
+
[dataSource]="timezones"
|
|
2215
|
+
textField="text"
|
|
2216
|
+
valueField="value"
|
|
2217
|
+
(onValueChanged)="onTimezoneChange($event)"
|
|
2218
|
+
/>
|
|
2219
|
+
</div>
|
|
2220
|
+
`, isInline: true, styles: [".ax-scheduler-picker-timezone-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2221
|
+
}
|
|
2222
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerTimezoneSelectorComponent, decorators: [{
|
|
2223
|
+
type: Component,
|
|
2224
|
+
args: [{ selector: 'ax-scheduler-picker-timezone-selector', template: `
|
|
2225
|
+
<div class="ax-scheduler-picker-timezone-selector">
|
|
2226
|
+
<label class="ax-scheduler-picker-label">
|
|
2227
|
+
{{ '@acorex:schedulerPicker.labels.timezone' | translate | async }}
|
|
2228
|
+
</label>
|
|
2229
|
+
<ax-select-box
|
|
2230
|
+
[value]="timezone() || 'UTC'"
|
|
2231
|
+
[dataSource]="timezones"
|
|
2232
|
+
textField="text"
|
|
2233
|
+
valueField="value"
|
|
2234
|
+
(onValueChanged)="onTimezoneChange($event)"
|
|
2235
|
+
/>
|
|
2236
|
+
</div>
|
|
2237
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [FormsModule, AXSelectBoxComponent, AXTranslatorPipe, AsyncPipe], styles: [".ax-scheduler-picker-timezone-selector{display:flex;flex-direction:column;gap:.5rem}.ax-scheduler-picker-label{color:var(--ax-comp-scheduler-picker-label-color);font-size:var(--ax-comp-scheduler-picker-label-font-size);font-weight:var(--ax-comp-scheduler-picker-label-font-weight)}\n"] }]
|
|
2238
|
+
}], propDecorators: { timezone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timezone", required: false }] }], timezoneChange: [{ type: i0.Output, args: ["timezoneChange"] }] } });
|
|
2239
|
+
|
|
2240
|
+
/**
|
|
2241
|
+
* Demo configuration panel for scheduler picker
|
|
2242
|
+
* Provides interactive controls to customize scheduler picker settings
|
|
2243
|
+
*/
|
|
2244
|
+
class AXSchedulerPickerConfigComponent {
|
|
2245
|
+
constructor() {
|
|
2246
|
+
// Outputs
|
|
2247
|
+
this.configChange = output();
|
|
2248
|
+
this.modeChange = output();
|
|
2249
|
+
// Mode selection
|
|
2250
|
+
this.selectedMode = signal('daily', ...(ngDevMode ? [{ debugName: "selectedMode" }] : []));
|
|
2251
|
+
this.modeOptions = [
|
|
2252
|
+
{ value: 'hourly', text: 'Hourly' },
|
|
2253
|
+
{ value: 'daily', text: 'Daily' },
|
|
2254
|
+
{ value: 'weekly', text: 'Weekly' },
|
|
2255
|
+
{ value: 'monthly', text: 'Monthly' },
|
|
2256
|
+
{ value: 'yearly', text: 'Yearly' },
|
|
2257
|
+
];
|
|
2258
|
+
// Configuration controls - Global
|
|
2259
|
+
this.showInterval = signal(true, ...(ngDevMode ? [{ debugName: "showInterval" }] : []));
|
|
2260
|
+
this.showStartCondition = signal(true, ...(ngDevMode ? [{ debugName: "showStartCondition" }] : []));
|
|
2261
|
+
this.showEndConditions = signal(true, ...(ngDevMode ? [{ debugName: "showEndConditions" }] : []));
|
|
2262
|
+
this.showExclusions = signal(false, ...(ngDevMode ? [{ debugName: "showExclusions" }] : []));
|
|
2263
|
+
this.showInclusions = signal(false, ...(ngDevMode ? [{ debugName: "showInclusions" }] : []));
|
|
2264
|
+
// Configuration controls - Mode specific
|
|
2265
|
+
this.showWeekdaysOnly = signal(false, ...(ngDevMode ? [{ debugName: "showWeekdaysOnly" }] : []));
|
|
2266
|
+
this.showWeekdaySelection = signal(true, ...(ngDevMode ? [{ debugName: "showWeekdaySelection" }] : []));
|
|
2267
|
+
this.monthlyRecurrenceMode = signal('specificDays', ...(ngDevMode ? [{ debugName: "monthlyRecurrenceMode" }] : []));
|
|
2268
|
+
this.yearlyRecurrenceMode = signal('specificDate', ...(ngDevMode ? [{ debugName: "yearlyRecurrenceMode" }] : []));
|
|
2269
|
+
this.showMonthSelection = signal(true, ...(ngDevMode ? [{ debugName: "showMonthSelection" }] : []));
|
|
2270
|
+
// Dynamic configuration based on selected mode
|
|
2271
|
+
this.config = computed(() => {
|
|
2272
|
+
const mode = this.selectedMode();
|
|
2273
|
+
const baseConfig = {
|
|
2274
|
+
mode,
|
|
2275
|
+
showStartCondition: this.showStartCondition(),
|
|
2276
|
+
showEndConditions: this.showEndConditions(),
|
|
2277
|
+
showExclusions: this.showExclusions(),
|
|
2278
|
+
showInclusions: this.showInclusions(),
|
|
2279
|
+
};
|
|
2280
|
+
switch (mode) {
|
|
2281
|
+
case 'hourly':
|
|
2282
|
+
baseConfig.options = {
|
|
2283
|
+
showInterval: this.showInterval(),
|
|
2284
|
+
};
|
|
2285
|
+
break;
|
|
2286
|
+
case 'daily':
|
|
2287
|
+
baseConfig.options = {
|
|
2288
|
+
showInterval: this.showInterval(),
|
|
2289
|
+
showWeekdaysOnly: this.showWeekdaysOnly(),
|
|
2290
|
+
};
|
|
2291
|
+
break;
|
|
2292
|
+
case 'weekly':
|
|
2293
|
+
baseConfig.options = {
|
|
2294
|
+
showInterval: this.showInterval(),
|
|
2295
|
+
showWeekdaySelection: this.showWeekdaySelection(),
|
|
2296
|
+
};
|
|
2297
|
+
break;
|
|
2298
|
+
case 'monthly':
|
|
2299
|
+
baseConfig.options = {
|
|
2300
|
+
showInterval: this.showInterval(),
|
|
2301
|
+
recurrenceMode: this.monthlyRecurrenceMode(),
|
|
2302
|
+
};
|
|
2303
|
+
break;
|
|
2304
|
+
case 'yearly':
|
|
2305
|
+
baseConfig.options = {
|
|
2306
|
+
showInterval: this.showInterval(),
|
|
2307
|
+
recurrenceMode: this.yearlyRecurrenceMode(),
|
|
2308
|
+
showMonthSelection: this.showMonthSelection(),
|
|
2309
|
+
};
|
|
2310
|
+
break;
|
|
2311
|
+
}
|
|
2312
|
+
return baseConfig;
|
|
2313
|
+
}, ...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
2314
|
+
// Emit config changes whenever any signal changes
|
|
2315
|
+
effect(() => {
|
|
2316
|
+
const currentConfig = this.config();
|
|
2317
|
+
this.configChange.emit(currentConfig);
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
2320
|
+
onModeChange(mode) {
|
|
2321
|
+
this.selectedMode.set(mode);
|
|
2322
|
+
this.modeChange.emit(mode);
|
|
2323
|
+
}
|
|
2324
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2325
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXSchedulerPickerConfigComponent, isStandalone: true, selector: "ax-scheduler-picker-config", outputs: { configChange: "configChange", modeChange: "modeChange" }, ngImport: i0, template: "<div class=\"ax-scheduler-picker-config\">\n <h3>Configuration</h3>\n\n <!-- Mode Selector -->\n <div class=\"control-group\">\n <label>Mode</label>\n <ax-select-box\n [dataSource]=\"modeOptions\"\n [textField]=\"'text'\"\n [valueField]=\"'value'\"\n [value]=\"selectedMode()\"\n (onValueChanged)=\"onModeChange($event.value)\"\n />\n </div>\n\n <!-- Global Options -->\n <div class=\"control-group\">\n <label>Global Options</label>\n <div class=\"switch-group\">\n <span>Show Interval</span>\n <ax-switch [(value)]=\"showInterval\" />\n </div>\n <div class=\"switch-group\">\n <span>Show Start Condition</span>\n <ax-switch [(value)]=\"showStartCondition\" />\n </div>\n <div class=\"switch-group\">\n <span>Show End Conditions</span>\n <ax-switch [(value)]=\"showEndConditions\" />\n </div>\n <div class=\"switch-group\">\n <span>Show Exclusions</span>\n <ax-switch [(value)]=\"showExclusions\" />\n </div>\n <div class=\"switch-group\">\n <span>Show Inclusions</span>\n <ax-switch [(value)]=\"showInclusions\" />\n </div>\n </div>\n\n <!-- Mode-Specific Options -->\n @if (selectedMode() === 'daily') {\n <div class=\"control-group\">\n <label>Daily Options</label>\n <div class=\"switch-group\">\n <span>Show Weekdays Only</span>\n <ax-switch [(value)]=\"showWeekdaysOnly\" />\n </div>\n </div>\n }\n \n @if (selectedMode() === 'weekly') {\n <div class=\"control-group\">\n <label>Weekly Options</label>\n <div class=\"switch-group\">\n <span>Show Weekday Selection</span>\n <ax-switch [(value)]=\"showWeekdaySelection\" />\n </div>\n </div>\n }\n \n @if (selectedMode() === 'monthly') {\n <div class=\"control-group\">\n <label>Monthly Options</label>\n <div class=\"control-subgroup\">\n <label>Recurrence Mode</label>\n <ax-select-box\n [dataSource]=\"[\n { value: 'none', text: 'None' },\n { value: 'specificDays', text: 'Specific Days' },\n { value: 'occurrence', text: 'Occurrence' }\n ]\"\n [textField]=\"'text'\"\n [valueField]=\"'value'\"\n [value]=\"monthlyRecurrenceMode()\"\n (onValueChanged)=\"monthlyRecurrenceMode.set($event.value)\"\n />\n </div>\n </div>\n }\n \n @if (selectedMode() === 'yearly') {\n <div class=\"control-group\">\n <label>Yearly Options</label>\n <div class=\"control-subgroup\">\n <label>Recurrence Mode</label>\n <ax-select-box\n [dataSource]=\"[\n { value: 'none', text: 'None' },\n { value: 'specificDate', text: 'Specific Date' },\n { value: 'occurrence', text: 'Occurrence' }\n ]\"\n [textField]=\"'text'\"\n [valueField]=\"'value'\"\n [value]=\"yearlyRecurrenceMode()\"\n (onValueChanged)=\"yearlyRecurrenceMode.set($event.value)\"\n />\n </div>\n <div class=\"switch-group\">\n <span>Show Month Selection</span>\n <ax-switch [(value)]=\"showMonthSelection\" />\n </div>\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-config{background:var(--ax-sys-color-surface-container);padding:1.25rem;border-radius:var(--ax-sys-border-radius-md)}.ax-scheduler-picker-config h3{margin:0 0 1.25rem;font-size:1rem;font-weight:600;color:var(--ax-sys-color-on-surface)}.ax-scheduler-picker-config .control-group{margin-bottom:1.25rem}.ax-scheduler-picker-config .control-group:last-child{margin-bottom:0}.ax-scheduler-picker-config .control-group>label{display:block;font-size:.875rem;font-weight:500;color:var(--ax-sys-color-on-surface-variant);margin-bottom:.5rem}.ax-scheduler-picker-config .control-group ax-select-box{width:100%}.ax-scheduler-picker-config .control-subgroup{margin-bottom:.75rem}.ax-scheduler-picker-config .control-subgroup label{display:block;font-size:.8125rem;font-weight:500;color:var(--ax-sys-color-on-surface-variant);margin-bottom:.375rem}.ax-scheduler-picker-config .control-subgroup ax-select-box{width:100%}.ax-scheduler-picker-config .switch-group{display:flex;align-items:center;justify-content:space-between;padding:.5rem 0;gap:.75rem}.ax-scheduler-picker-config .switch-group span{font-size:.875rem;color:var(--ax-sys-color-on-surface)}.ax-scheduler-picker-config .switch-group ax-switch{flex-shrink:0}\n"], dependencies: [{ kind: "component", type: AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "component", type: AXSwitchComponent, selector: "ax-switch", inputs: ["disabled", "readonly", "color", "tabIndex", "value", "name", "isLoading"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged", "readonlyChange", "disabledChange"] }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2326
|
+
}
|
|
2327
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXSchedulerPickerConfigComponent, decorators: [{
|
|
2328
|
+
type: Component,
|
|
2329
|
+
args: [{ selector: 'ax-scheduler-picker-config', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [AXSelectBoxComponent, AXSwitchComponent, FormsModule], template: "<div class=\"ax-scheduler-picker-config\">\n <h3>Configuration</h3>\n\n <!-- Mode Selector -->\n <div class=\"control-group\">\n <label>Mode</label>\n <ax-select-box\n [dataSource]=\"modeOptions\"\n [textField]=\"'text'\"\n [valueField]=\"'value'\"\n [value]=\"selectedMode()\"\n (onValueChanged)=\"onModeChange($event.value)\"\n />\n </div>\n\n <!-- Global Options -->\n <div class=\"control-group\">\n <label>Global Options</label>\n <div class=\"switch-group\">\n <span>Show Interval</span>\n <ax-switch [(value)]=\"showInterval\" />\n </div>\n <div class=\"switch-group\">\n <span>Show Start Condition</span>\n <ax-switch [(value)]=\"showStartCondition\" />\n </div>\n <div class=\"switch-group\">\n <span>Show End Conditions</span>\n <ax-switch [(value)]=\"showEndConditions\" />\n </div>\n <div class=\"switch-group\">\n <span>Show Exclusions</span>\n <ax-switch [(value)]=\"showExclusions\" />\n </div>\n <div class=\"switch-group\">\n <span>Show Inclusions</span>\n <ax-switch [(value)]=\"showInclusions\" />\n </div>\n </div>\n\n <!-- Mode-Specific Options -->\n @if (selectedMode() === 'daily') {\n <div class=\"control-group\">\n <label>Daily Options</label>\n <div class=\"switch-group\">\n <span>Show Weekdays Only</span>\n <ax-switch [(value)]=\"showWeekdaysOnly\" />\n </div>\n </div>\n }\n \n @if (selectedMode() === 'weekly') {\n <div class=\"control-group\">\n <label>Weekly Options</label>\n <div class=\"switch-group\">\n <span>Show Weekday Selection</span>\n <ax-switch [(value)]=\"showWeekdaySelection\" />\n </div>\n </div>\n }\n \n @if (selectedMode() === 'monthly') {\n <div class=\"control-group\">\n <label>Monthly Options</label>\n <div class=\"control-subgroup\">\n <label>Recurrence Mode</label>\n <ax-select-box\n [dataSource]=\"[\n { value: 'none', text: 'None' },\n { value: 'specificDays', text: 'Specific Days' },\n { value: 'occurrence', text: 'Occurrence' }\n ]\"\n [textField]=\"'text'\"\n [valueField]=\"'value'\"\n [value]=\"monthlyRecurrenceMode()\"\n (onValueChanged)=\"monthlyRecurrenceMode.set($event.value)\"\n />\n </div>\n </div>\n }\n \n @if (selectedMode() === 'yearly') {\n <div class=\"control-group\">\n <label>Yearly Options</label>\n <div class=\"control-subgroup\">\n <label>Recurrence Mode</label>\n <ax-select-box\n [dataSource]=\"[\n { value: 'none', text: 'None' },\n { value: 'specificDate', text: 'Specific Date' },\n { value: 'occurrence', text: 'Occurrence' }\n ]\"\n [textField]=\"'text'\"\n [valueField]=\"'value'\"\n [value]=\"yearlyRecurrenceMode()\"\n (onValueChanged)=\"yearlyRecurrenceMode.set($event.value)\"\n />\n </div>\n <div class=\"switch-group\">\n <span>Show Month Selection</span>\n <ax-switch [(value)]=\"showMonthSelection\" />\n </div>\n </div>\n }\n</div>\n", styles: [".ax-scheduler-picker-config{background:var(--ax-sys-color-surface-container);padding:1.25rem;border-radius:var(--ax-sys-border-radius-md)}.ax-scheduler-picker-config h3{margin:0 0 1.25rem;font-size:1rem;font-weight:600;color:var(--ax-sys-color-on-surface)}.ax-scheduler-picker-config .control-group{margin-bottom:1.25rem}.ax-scheduler-picker-config .control-group:last-child{margin-bottom:0}.ax-scheduler-picker-config .control-group>label{display:block;font-size:.875rem;font-weight:500;color:var(--ax-sys-color-on-surface-variant);margin-bottom:.5rem}.ax-scheduler-picker-config .control-group ax-select-box{width:100%}.ax-scheduler-picker-config .control-subgroup{margin-bottom:.75rem}.ax-scheduler-picker-config .control-subgroup label{display:block;font-size:.8125rem;font-weight:500;color:var(--ax-sys-color-on-surface-variant);margin-bottom:.375rem}.ax-scheduler-picker-config .control-subgroup ax-select-box{width:100%}.ax-scheduler-picker-config .switch-group{display:flex;align-items:center;justify-content:space-between;padding:.5rem 0;gap:.75rem}.ax-scheduler-picker-config .switch-group span{font-size:.875rem;color:var(--ax-sys-color-on-surface)}.ax-scheduler-picker-config .switch-group ax-switch{flex-shrink:0}\n"] }]
|
|
2330
|
+
}], ctorParameters: () => [], propDecorators: { configChange: [{ type: i0.Output, args: ["configChange"] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }] } });
|
|
2331
|
+
|
|
2332
|
+
// Main component
|
|
2333
|
+
|
|
2334
|
+
/**
|
|
2335
|
+
* Generated bundle index. Do not edit.
|
|
2336
|
+
*/
|
|
2337
|
+
|
|
2338
|
+
export { AXSchedulerPickerComponent, AXSchedulerPickerConfigComponent, AXSchedulerPickerDailyDefaultConfig, AXSchedulerPickerDailyPanelComponent, AXSchedulerPickerDaySelectorComponent, AXSchedulerPickerEndConditionSelectorComponent, AXSchedulerPickerExclusionManagerComponent, AXSchedulerPickerHourlyDefaultConfig, AXSchedulerPickerHourlyPanelComponent, AXSchedulerPickerInclusionManagerComponent, AXSchedulerPickerIntervalSelectorComponent, AXSchedulerPickerMonthSelectorComponent, AXSchedulerPickerMonthlyDefaultConfig, AXSchedulerPickerMonthlyPanelComponent, AXSchedulerPickerOccurrenceSelectorComponent, AXSchedulerPickerService, AXSchedulerPickerStartConditionSelectorComponent, AXSchedulerPickerTimeSelectorComponent, AXSchedulerPickerTimezoneSelectorComponent, AXSchedulerPickerWeeklyDefaultConfig, AXSchedulerPickerWeeklyPanelComponent, AXSchedulerPickerYearlyDefaultConfig, AXSchedulerPickerYearlyPanelComponent, AX_SCHEDULER_PICKER_DAILY_CONFIG, AX_SCHEDULER_PICKER_DAYS_OF_WEEK, AX_SCHEDULER_PICKER_DAY_TRANSLATION_KEYS, AX_SCHEDULER_PICKER_DEFAULT_FIRST_DAY_OF_WEEK, AX_SCHEDULER_PICKER_DEFAULT_LOCALE, AX_SCHEDULER_PICKER_DEFAULT_OCCURRENCES, AX_SCHEDULER_PICKER_DEFAULT_TIME_FORMAT, AX_SCHEDULER_PICKER_DEFAULT_TIME_PRECISION, AX_SCHEDULER_PICKER_HOURLY_CONFIG, AX_SCHEDULER_PICKER_MONTHLY_CONFIG, AX_SCHEDULER_PICKER_MONTHS, AX_SCHEDULER_PICKER_MONTH_TRANSLATION_KEYS, AX_SCHEDULER_PICKER_OCCURRENCE_POSITIONS, AX_SCHEDULER_PICKER_RRULE_DAY_KEYS, AX_SCHEDULER_PICKER_WEEKDAY_END, AX_SCHEDULER_PICKER_WEEKDAY_START, AX_SCHEDULER_PICKER_WEEKLY_CONFIG, AX_SCHEDULER_PICKER_YEARLY_CONFIG, dateExistsInArray, getDayTranslationKey, getDefaultSchedulerPickerConfig, getMonthTranslationKey, getRRuleDayKey, isSameDate, normalizeDate, reorderDaysByFirstDay };
|
|
2339
|
+
//# sourceMappingURL=acorex-components-scheduler-picker.mjs.map
|