@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,689 @@
|
|
|
1
|
+
import { moveItemInArray, transferArrayItem, AXDragDirective, AXDragHandleDirective, AXDropListDirective } from '@acorex/cdk/drag-drop';
|
|
2
|
+
import { AXBadgeComponent } from '@acorex/components/badge';
|
|
3
|
+
import { AXButtonComponent } from '@acorex/components/button';
|
|
4
|
+
import { AXCheckBoxComponent } from '@acorex/components/check-box';
|
|
5
|
+
import { AXDecoratorIconComponent } from '@acorex/components/decorators';
|
|
6
|
+
import * as i1 from '@angular/common';
|
|
7
|
+
import { CommonModule, NgTemplateOutlet } from '@angular/common';
|
|
8
|
+
import * as i0 from '@angular/core';
|
|
9
|
+
import { model, input, output, signal, effect, ViewEncapsulation, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
|
|
10
|
+
import * as i2 from '@angular/forms';
|
|
11
|
+
import { FormsModule } from '@angular/forms';
|
|
12
|
+
|
|
13
|
+
class AXTree2Component {
|
|
14
|
+
constructor() {
|
|
15
|
+
// Constants for list ID generation
|
|
16
|
+
this.ROOT_LIST_ID = 'ax-tree-root-list';
|
|
17
|
+
this.NODE_DROP_PREFIX = 'ax-tree-node-drop-';
|
|
18
|
+
this.LIST_PREFIX = 'ax-tree-list-';
|
|
19
|
+
/** Tree data nodes */
|
|
20
|
+
this.nodes = model.required(...(ngDevMode ? [{ debugName: "nodes" }] : []));
|
|
21
|
+
/** Whether to show checkboxes for selection */
|
|
22
|
+
this.showCheckbox = input(true, ...(ngDevMode ? [{ debugName: "showCheckbox" }] : []));
|
|
23
|
+
/** Drag and drop mode: 'none' (disabled), 'handler' (drag handle), 'item' (entire item) */
|
|
24
|
+
this.dragMode = input('handler', ...(ngDevMode ? [{ debugName: "dragMode" }] : []));
|
|
25
|
+
/** Drag operation type: 'order-only' (reorder only), 'move' (move between parents), 'both' (allow both) */
|
|
26
|
+
this.dragOperationType = input('both', ...(ngDevMode ? [{ debugName: "dragOperationType" }] : []));
|
|
27
|
+
/** Whether to show icons */
|
|
28
|
+
this.showIcons = input(true, ...(ngDevMode ? [{ debugName: "showIcons" }] : []));
|
|
29
|
+
/** Whether to show children count badge */
|
|
30
|
+
this.showChildrenBadge = input(true, ...(ngDevMode ? [{ debugName: "showChildrenBadge" }] : []));
|
|
31
|
+
/** Custom icon for expanded nodes */
|
|
32
|
+
this.expandedIcon = input('fa-solid fa-chevron-down', ...(ngDevMode ? [{ debugName: "expandedIcon" }] : []));
|
|
33
|
+
/** Custom icon for collapsed nodes */
|
|
34
|
+
this.collapsedIcon = input('fa-solid fa-chevron-right', ...(ngDevMode ? [{ debugName: "collapsedIcon" }] : []));
|
|
35
|
+
/** Indent size in pixels for each level */
|
|
36
|
+
this.indentSize = input(12, ...(ngDevMode ? [{ debugName: "indentSize" }] : []));
|
|
37
|
+
/** Node height in pixels */
|
|
38
|
+
this.nodeHeight = input('normal', ...(ngDevMode ? [{ debugName: "nodeHeight" }] : []));
|
|
39
|
+
/** Visual style variant */
|
|
40
|
+
this.look = input('default', ...(ngDevMode ? [{ debugName: "look" }] : []));
|
|
41
|
+
/** Custom template for tree items */
|
|
42
|
+
this.itemTemplate = input(...(ngDevMode ? [undefined, { debugName: "itemTemplate" }] : []));
|
|
43
|
+
/** Lazy load function for fetching children */
|
|
44
|
+
this.lazyLoad = input(...(ngDevMode ? [undefined, { debugName: "lazyLoad" }] : []));
|
|
45
|
+
/** Whether to enable lazy loading */
|
|
46
|
+
this.enableLazyLoad = input(false, ...(ngDevMode ? [{ debugName: "enableLazyLoad" }] : []));
|
|
47
|
+
/** Emitted before a drop operation - set canceled to true to prevent drop */
|
|
48
|
+
this.onBeforeDrop = output();
|
|
49
|
+
/** Emitted when a node is toggled (expanded/collapsed) */
|
|
50
|
+
this.onNodeToggle = output();
|
|
51
|
+
/** Emitted when a node is selected/deselected */
|
|
52
|
+
this.onNodeSelect = output();
|
|
53
|
+
/** Emitted when nodes are reordered within the same parent */
|
|
54
|
+
this.onOrderChange = output();
|
|
55
|
+
/** Emitted when a node is moved to a different parent */
|
|
56
|
+
this.onMoveChange = output();
|
|
57
|
+
/** Emitted for any item change (order or move) */
|
|
58
|
+
this.onItemsChange = output();
|
|
59
|
+
/** Internal signal for tracking loading state */
|
|
60
|
+
this.loadingNodes = signal(new Set(), ...(ngDevMode ? [{ debugName: "loadingNodes" }] : []));
|
|
61
|
+
/** Effect to handle lazy load function changes */
|
|
62
|
+
this.#lazyLoadEffect = effect(() => {
|
|
63
|
+
const lazyLoadFn = this.lazyLoad();
|
|
64
|
+
const enabled = this.enableLazyLoad();
|
|
65
|
+
if (lazyLoadFn && enabled) {
|
|
66
|
+
// Initialize lazy loading state
|
|
67
|
+
this.updateHasChildrenFlags(this.nodes());
|
|
68
|
+
}
|
|
69
|
+
}, ...(ngDevMode ? [{ debugName: "#lazyLoadEffect" }] : []));
|
|
70
|
+
}
|
|
71
|
+
/** Effect to handle lazy load function changes */
|
|
72
|
+
#lazyLoadEffect;
|
|
73
|
+
/**
|
|
74
|
+
* Toggle node expansion state with lazy loading support
|
|
75
|
+
*/
|
|
76
|
+
async toggleNode(node, event) {
|
|
77
|
+
if (node.disabled)
|
|
78
|
+
return;
|
|
79
|
+
const hasChildren = this.hasChildren(node);
|
|
80
|
+
const canLazyLoad = this.canLazyLoad(node);
|
|
81
|
+
if (hasChildren || canLazyLoad) {
|
|
82
|
+
const willExpand = !node.expanded;
|
|
83
|
+
if (willExpand && canLazyLoad) {
|
|
84
|
+
// Lazy load children before expanding
|
|
85
|
+
await this.loadNodeChildren(node);
|
|
86
|
+
}
|
|
87
|
+
node.expanded = willExpand;
|
|
88
|
+
this.nodes.set([...this.nodes()]);
|
|
89
|
+
this.onNodeToggle.emit({ component: this, node, nativeEvent: event });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Load children for a node using lazy loading
|
|
94
|
+
*/
|
|
95
|
+
async loadNodeChildren(node) {
|
|
96
|
+
const lazyLoadFn = this.lazyLoad();
|
|
97
|
+
if (!lazyLoadFn || node.loading)
|
|
98
|
+
return;
|
|
99
|
+
try {
|
|
100
|
+
node.loading = true;
|
|
101
|
+
this.loadingNodes.update((set) => new Set(set).add(node.id));
|
|
102
|
+
this.nodes.set([...this.nodes()]);
|
|
103
|
+
const children = await lazyLoadFn(node);
|
|
104
|
+
node.children = children;
|
|
105
|
+
node.childrenCount = children.length;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error('Failed to load children:', error);
|
|
109
|
+
node.childrenCount = 0;
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
node.loading = false;
|
|
113
|
+
this.loadingNodes.update((set) => {
|
|
114
|
+
const newSet = new Set(set);
|
|
115
|
+
newSet.delete(node.id);
|
|
116
|
+
return newSet;
|
|
117
|
+
});
|
|
118
|
+
this.nodes.set([...this.nodes()]);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Update childrenCount flags for lazy loading
|
|
123
|
+
*/
|
|
124
|
+
updateHasChildrenFlags(nodes) {
|
|
125
|
+
nodes.forEach((node) => {
|
|
126
|
+
if (node.childrenCount === undefined && !node.children) {
|
|
127
|
+
node.childrenCount = 0;
|
|
128
|
+
}
|
|
129
|
+
if (node.children) {
|
|
130
|
+
this.updateHasChildrenFlags(node.children);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Toggle node selection state with indeterminate support
|
|
136
|
+
*/
|
|
137
|
+
toggleSelection(node, event) {
|
|
138
|
+
// CRITICAL: Only process if this is a real user interaction
|
|
139
|
+
// Prevents cascade when parent state changes trigger checkbox ngModelChange
|
|
140
|
+
if (!event.isUserInteraction) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Handle null value (indeterminate state clicked) - treat as select
|
|
144
|
+
const newValue = event.value === null ? true : event.value;
|
|
145
|
+
node.selected = newValue;
|
|
146
|
+
node.indeterminate = false; // Clear indeterminate when explicitly toggled
|
|
147
|
+
// Select/deselect all children recursively
|
|
148
|
+
if (node.children) {
|
|
149
|
+
this.selectAllChildren(node.children, newValue);
|
|
150
|
+
}
|
|
151
|
+
// Update parent states up the tree
|
|
152
|
+
this.updateParentStates(this.nodes(), node);
|
|
153
|
+
this.nodes.set([...this.nodes()]);
|
|
154
|
+
this.onNodeSelect.emit({
|
|
155
|
+
component: this,
|
|
156
|
+
node,
|
|
157
|
+
isUserInteraction: event.isUserInteraction,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Recursively select/deselect all children
|
|
162
|
+
*/
|
|
163
|
+
selectAllChildren(children, selected) {
|
|
164
|
+
children.forEach((child) => {
|
|
165
|
+
child.selected = selected;
|
|
166
|
+
child.indeterminate = false;
|
|
167
|
+
if (child.children) {
|
|
168
|
+
this.selectAllChildren(child.children, selected);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Update parent node states based on children selection
|
|
174
|
+
*/
|
|
175
|
+
updateParentStates(nodes, changedNode) {
|
|
176
|
+
const parent = this.findParentNode(nodes, changedNode);
|
|
177
|
+
if (!parent || !parent.children)
|
|
178
|
+
return;
|
|
179
|
+
const { allSelected, someSelected } = this.getChildrenSelectionState(parent.children);
|
|
180
|
+
if (allSelected) {
|
|
181
|
+
// All children selected → parent is selected
|
|
182
|
+
parent.selected = true;
|
|
183
|
+
parent.indeterminate = false;
|
|
184
|
+
}
|
|
185
|
+
else if (someSelected) {
|
|
186
|
+
// Some children selected → parent is indeterminate
|
|
187
|
+
// Keep selected=true to maintain consistent state and prevent issues with deleteSelected()
|
|
188
|
+
parent.selected = true;
|
|
189
|
+
parent.indeterminate = true;
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
// No children selected → parent is unselected
|
|
193
|
+
parent.selected = false;
|
|
194
|
+
parent.indeterminate = false;
|
|
195
|
+
}
|
|
196
|
+
// Recursively update grandparents
|
|
197
|
+
this.updateParentStates(nodes, parent);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get selection state of children
|
|
201
|
+
*/
|
|
202
|
+
getChildrenSelectionState(children) {
|
|
203
|
+
let selectedCount = 0;
|
|
204
|
+
let indeterminateCount = 0;
|
|
205
|
+
children.forEach((child) => {
|
|
206
|
+
// Only count fully selected children (not indeterminate)
|
|
207
|
+
if (child.selected && !child.indeterminate)
|
|
208
|
+
selectedCount++;
|
|
209
|
+
if (child.indeterminate)
|
|
210
|
+
indeterminateCount++;
|
|
211
|
+
});
|
|
212
|
+
const allSelected = selectedCount === children.length;
|
|
213
|
+
const someSelected = selectedCount > 0 || indeterminateCount > 0;
|
|
214
|
+
return { allSelected, someSelected };
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Find parent node of a given node
|
|
218
|
+
*/
|
|
219
|
+
findParentNode(nodes, targetNode) {
|
|
220
|
+
for (const node of nodes) {
|
|
221
|
+
if (node.children?.some((child) => child.id === targetNode.id)) {
|
|
222
|
+
return node;
|
|
223
|
+
}
|
|
224
|
+
if (node.children) {
|
|
225
|
+
const found = this.findParentNode(node.children, targetNode);
|
|
226
|
+
if (found)
|
|
227
|
+
return found;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Handle drop events for tree nodes
|
|
234
|
+
*/
|
|
235
|
+
onDrop(event, parentNode) {
|
|
236
|
+
const targetArray = parentNode?.children ?? this.nodes();
|
|
237
|
+
const isReordering = event.previousContainer === event.container;
|
|
238
|
+
if (isReordering) {
|
|
239
|
+
this.handleReorder(event, targetArray, parentNode);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
this.handleMove(event, targetArray, parentNode);
|
|
243
|
+
}
|
|
244
|
+
this.nodes.set([...this.nodes()]);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Handle drop events when dropping directly onto a node (to make it a child)
|
|
248
|
+
*/
|
|
249
|
+
onDropOntoNode(event, targetNode) {
|
|
250
|
+
if (!this.canMoveToParent())
|
|
251
|
+
return;
|
|
252
|
+
const sourceListId = event.previousContainer.element.id;
|
|
253
|
+
const sourceArray = this.getArrayByListId(sourceListId);
|
|
254
|
+
if (!sourceArray)
|
|
255
|
+
return;
|
|
256
|
+
const movedNode = sourceArray[event.previousIndex];
|
|
257
|
+
if (!this.isValidDropTarget(movedNode, targetNode))
|
|
258
|
+
return;
|
|
259
|
+
if (!this.emitBeforeDropEvent(movedNode, sourceListId, targetNode, event.previousIndex, 0))
|
|
260
|
+
return;
|
|
261
|
+
// Initialize children array and perform transfer
|
|
262
|
+
targetNode.children ??= [];
|
|
263
|
+
sourceArray.splice(event.previousIndex, 1);
|
|
264
|
+
targetNode.children.unshift(movedNode);
|
|
265
|
+
targetNode.expanded = true;
|
|
266
|
+
// Emit events
|
|
267
|
+
this.emitDropEvents(movedNode, this.findParentByListId(sourceListId), targetNode, event.previousIndex, 0, false);
|
|
268
|
+
this.nodes.set([...this.nodes()]);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Get array reference by drop list ID
|
|
272
|
+
*/
|
|
273
|
+
getArrayByListId(listId) {
|
|
274
|
+
if (listId === this.ROOT_LIST_ID) {
|
|
275
|
+
return this.nodes();
|
|
276
|
+
}
|
|
277
|
+
if (listId.startsWith(this.NODE_DROP_PREFIX)) {
|
|
278
|
+
const nodeId = listId.replace(this.NODE_DROP_PREFIX, '');
|
|
279
|
+
const node = this.findNodeById(this.nodes(), nodeId);
|
|
280
|
+
return node ? [node] : null;
|
|
281
|
+
}
|
|
282
|
+
const nodeId = listId.replace(this.LIST_PREFIX, '');
|
|
283
|
+
const node = this.findNodeById(this.nodes(), nodeId);
|
|
284
|
+
return node?.children ?? null;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Find parent node by list ID
|
|
288
|
+
*/
|
|
289
|
+
findParentByListId(listId) {
|
|
290
|
+
if (listId === this.ROOT_LIST_ID) {
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
const prefix = listId.startsWith(this.NODE_DROP_PREFIX) ? this.NODE_DROP_PREFIX : this.LIST_PREFIX;
|
|
294
|
+
const nodeId = listId.replace(prefix, '');
|
|
295
|
+
return this.findNodeById(this.nodes(), nodeId) ?? undefined;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Find a node by ID in the tree
|
|
299
|
+
*/
|
|
300
|
+
findNodeById(nodes, id) {
|
|
301
|
+
for (const node of nodes) {
|
|
302
|
+
if (node.id === id)
|
|
303
|
+
return node;
|
|
304
|
+
if (node.children) {
|
|
305
|
+
const found = this.findNodeById(node.children, id);
|
|
306
|
+
if (found)
|
|
307
|
+
return found;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Check if targetNode is a descendant of ancestorNode (or the same node)
|
|
314
|
+
* Prevents circular references by checking if target exists in ancestor's children tree
|
|
315
|
+
*/
|
|
316
|
+
isNodeDescendantOf(targetNode, ancestorNode) {
|
|
317
|
+
// First check: prevent dropping a node into itself
|
|
318
|
+
if (targetNode.id === ancestorNode.id) {
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
if (!ancestorNode.children || ancestorNode.children.length === 0) {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
for (const child of ancestorNode.children) {
|
|
325
|
+
// Direct child match
|
|
326
|
+
if (child.id === targetNode.id) {
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
// Recursive check in deeper levels
|
|
330
|
+
if (this.isNodeDescendantOf(targetNode, child)) {
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Generate unique list ID for each node
|
|
338
|
+
*/
|
|
339
|
+
getListId(node) {
|
|
340
|
+
return node ? `${this.LIST_PREFIX}${node.id}` : this.ROOT_LIST_ID;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Expand all nodes in the tree (with lazy loading support)
|
|
344
|
+
*/
|
|
345
|
+
async expandAll() {
|
|
346
|
+
await this.setExpandedState(this.nodes(), true);
|
|
347
|
+
this.nodes.set([...this.nodes()]);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Collapse all nodes in the tree
|
|
351
|
+
*/
|
|
352
|
+
collapseAll() {
|
|
353
|
+
this.setExpandedState(this.nodes(), false);
|
|
354
|
+
this.nodes.set([...this.nodes()]);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Recursively set expanded state (with lazy loading)
|
|
358
|
+
*/
|
|
359
|
+
async setExpandedState(nodes, expanded) {
|
|
360
|
+
for (const node of nodes) {
|
|
361
|
+
const hasChildren = this.hasChildren(node);
|
|
362
|
+
const canLazyLoad = this.canLazyLoad(node);
|
|
363
|
+
if (hasChildren || canLazyLoad) {
|
|
364
|
+
if (expanded && canLazyLoad) {
|
|
365
|
+
await this.loadNodeChildren(node);
|
|
366
|
+
}
|
|
367
|
+
node.expanded = expanded;
|
|
368
|
+
if (node.children) {
|
|
369
|
+
await this.setExpandedState(node.children, expanded);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Get count of selected nodes
|
|
376
|
+
*/
|
|
377
|
+
getSelectedCount() {
|
|
378
|
+
return this.countSelected(this.nodes());
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Check if any nodes are selected
|
|
382
|
+
*/
|
|
383
|
+
hasSelection() {
|
|
384
|
+
return this.getSelectedCount() > 0;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Recursively count selected nodes
|
|
388
|
+
*/
|
|
389
|
+
countSelected(nodes) {
|
|
390
|
+
let count = 0;
|
|
391
|
+
nodes.forEach((node) => {
|
|
392
|
+
if (node.selected)
|
|
393
|
+
count++;
|
|
394
|
+
if (node.children) {
|
|
395
|
+
count += this.countSelected(node.children);
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
return count;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Get all selected nodes
|
|
402
|
+
*/
|
|
403
|
+
getSelectedNodes() {
|
|
404
|
+
const selected = [];
|
|
405
|
+
this.collectSelected(this.nodes(), selected);
|
|
406
|
+
return selected;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Recursively collect selected nodes
|
|
410
|
+
*/
|
|
411
|
+
collectSelected(nodes, result) {
|
|
412
|
+
nodes.forEach((node) => {
|
|
413
|
+
if (node.selected)
|
|
414
|
+
result.push(node);
|
|
415
|
+
if (node.children) {
|
|
416
|
+
this.collectSelected(node.children, result);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Delete selected nodes from the tree
|
|
422
|
+
*/
|
|
423
|
+
deleteSelected() {
|
|
424
|
+
this.removeSelected(this.nodes());
|
|
425
|
+
// Update all parent states after deletion to clear stale indeterminate states
|
|
426
|
+
this.updateAllParentStates(this.nodes());
|
|
427
|
+
this.nodes.set([...this.nodes()]);
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Select all nodes in the tree
|
|
431
|
+
*/
|
|
432
|
+
selectAll() {
|
|
433
|
+
this.setAllSelection(this.nodes(), true);
|
|
434
|
+
this.nodes.set([...this.nodes()]);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Deselect all nodes in the tree
|
|
438
|
+
*/
|
|
439
|
+
deselectAll() {
|
|
440
|
+
this.setAllSelection(this.nodes(), false);
|
|
441
|
+
this.nodes.set([...this.nodes()]);
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Find a node by ID in the tree
|
|
445
|
+
*/
|
|
446
|
+
findNode(id) {
|
|
447
|
+
return this.findNodeById(this.nodes(), id);
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Refresh the tree to trigger change detection
|
|
451
|
+
*/
|
|
452
|
+
refresh() {
|
|
453
|
+
this.nodes.set([...this.nodes()]);
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Recursively set selection state for all nodes
|
|
457
|
+
*/
|
|
458
|
+
setAllSelection(nodes, selected) {
|
|
459
|
+
nodes.forEach((node) => {
|
|
460
|
+
node.selected = selected;
|
|
461
|
+
node.indeterminate = false;
|
|
462
|
+
if (node.children) {
|
|
463
|
+
this.setAllSelection(node.children, selected);
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Recursively remove selected nodes
|
|
469
|
+
*/
|
|
470
|
+
removeSelected(nodes) {
|
|
471
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
472
|
+
// Only delete nodes that are fully selected (not indeterminate)
|
|
473
|
+
// Indeterminate parents should not be deleted
|
|
474
|
+
if (nodes[i].selected && !nodes[i].indeterminate) {
|
|
475
|
+
nodes.splice(i, 1);
|
|
476
|
+
}
|
|
477
|
+
else if (nodes[i].children) {
|
|
478
|
+
this.removeSelected(nodes[i].children ?? []);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Recursively update all parent states in the tree (used after deletion)
|
|
484
|
+
*/
|
|
485
|
+
updateAllParentStates(nodes) {
|
|
486
|
+
nodes.forEach((node) => {
|
|
487
|
+
if (node.children && node.children.length > 0) {
|
|
488
|
+
// First, recursively update nested children (bottom-up)
|
|
489
|
+
this.updateAllParentStates(node.children);
|
|
490
|
+
// Then update this node's state based on its children
|
|
491
|
+
const { allSelected, someSelected } = this.getChildrenSelectionState(node.children);
|
|
492
|
+
if (allSelected) {
|
|
493
|
+
node.selected = true;
|
|
494
|
+
node.indeterminate = false;
|
|
495
|
+
}
|
|
496
|
+
else if (someSelected) {
|
|
497
|
+
node.selected = true;
|
|
498
|
+
node.indeterminate = true;
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
node.selected = false;
|
|
502
|
+
node.indeterminate = false;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Check if a node is currently loading
|
|
509
|
+
*/
|
|
510
|
+
isNodeLoading(nodeId) {
|
|
511
|
+
return this.loadingNodes().has(nodeId);
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Get template context for a node
|
|
515
|
+
*/
|
|
516
|
+
getTemplateContext(node, level = 0) {
|
|
517
|
+
return {
|
|
518
|
+
$implicit: node,
|
|
519
|
+
node,
|
|
520
|
+
level,
|
|
521
|
+
expanded: node.expanded ?? false,
|
|
522
|
+
childrenCount: node.childrenCount ?? node.children?.length ?? 0,
|
|
523
|
+
loading: node.loading ?? false,
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Check if node should show expand toggle
|
|
528
|
+
*/
|
|
529
|
+
shouldShowExpandToggle(node) {
|
|
530
|
+
return this.hasChildren(node) || this.canLazyLoad(node);
|
|
531
|
+
}
|
|
532
|
+
// Helper methods for improved code reusability
|
|
533
|
+
/**
|
|
534
|
+
* Check if node has children
|
|
535
|
+
*/
|
|
536
|
+
hasChildren(node) {
|
|
537
|
+
return Boolean(node.children?.length);
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Check if node can be lazy loaded
|
|
541
|
+
*/
|
|
542
|
+
canLazyLoad(node) {
|
|
543
|
+
return this.enableLazyLoad() && Boolean(node.childrenCount && node.childrenCount > 0 && !this.hasChildren(node));
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Check if move operation is allowed based on dragOperationType
|
|
547
|
+
*/
|
|
548
|
+
canMoveToParent() {
|
|
549
|
+
if (this.dragOperationType() === 'order-only') {
|
|
550
|
+
console.warn('Moving between parents is disabled when dragOperationType is "order-only"');
|
|
551
|
+
return false;
|
|
552
|
+
}
|
|
553
|
+
return true;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Check if reorder operation is allowed based on dragOperationType
|
|
557
|
+
*/
|
|
558
|
+
canReorder() {
|
|
559
|
+
if (this.dragOperationType() === 'move') {
|
|
560
|
+
console.warn('Reordering is disabled when dragOperationType is "move"');
|
|
561
|
+
return false;
|
|
562
|
+
}
|
|
563
|
+
return true;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Validate if drop target is valid (prevent circular references)
|
|
567
|
+
*/
|
|
568
|
+
isValidDropTarget(movedNode, targetNode) {
|
|
569
|
+
if (movedNode.id === targetNode.id || this.isNodeDescendantOf(targetNode, movedNode)) {
|
|
570
|
+
console.warn('Cannot drop a node onto itself or its descendants');
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
return true;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Handle reordering within the same list
|
|
577
|
+
*/
|
|
578
|
+
handleReorder(event, targetArray, parentNode) {
|
|
579
|
+
if (!this.canReorder())
|
|
580
|
+
return;
|
|
581
|
+
const movedNode = targetArray[event.previousIndex];
|
|
582
|
+
moveItemInArray(targetArray, event.previousIndex, event.currentIndex);
|
|
583
|
+
this.emitDropEvents(movedNode, parentNode, parentNode, event.previousIndex, event.currentIndex, true);
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Handle moving between different lists
|
|
587
|
+
*/
|
|
588
|
+
handleMove(event, targetArray, parentNode) {
|
|
589
|
+
if (!this.canMoveToParent())
|
|
590
|
+
return;
|
|
591
|
+
const sourceListId = event.previousContainer.element.id;
|
|
592
|
+
const sourceArray = this.getArrayByListId(sourceListId);
|
|
593
|
+
if (!sourceArray)
|
|
594
|
+
return;
|
|
595
|
+
const movedNode = sourceArray[event.previousIndex];
|
|
596
|
+
// Prevent circular references
|
|
597
|
+
if (parentNode && !this.isValidDropTarget(movedNode, parentNode))
|
|
598
|
+
return;
|
|
599
|
+
// Check if user wants to cancel
|
|
600
|
+
if (!this.emitBeforeDropEvent(movedNode, sourceListId, parentNode, event.previousIndex, event.currentIndex)) {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
transferArrayItem(sourceArray, targetArray, event.previousIndex, event.currentIndex);
|
|
604
|
+
this.emitDropEvents(movedNode, this.findParentByListId(sourceListId), parentNode, event.previousIndex, event.currentIndex, false);
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Emit beforeDrop event and return whether to continue
|
|
608
|
+
*/
|
|
609
|
+
emitBeforeDropEvent(movedNode, sourceListId, currentParent, previousIndex, currentIndex) {
|
|
610
|
+
const beforeDropEvent = {
|
|
611
|
+
component: this,
|
|
612
|
+
movedNode,
|
|
613
|
+
previousParent: this.findParentByListId(sourceListId),
|
|
614
|
+
currentParent,
|
|
615
|
+
previousIndex,
|
|
616
|
+
currentIndex,
|
|
617
|
+
canceled: false,
|
|
618
|
+
};
|
|
619
|
+
this.onBeforeDrop.emit(beforeDropEvent);
|
|
620
|
+
if (beforeDropEvent.canceled) {
|
|
621
|
+
console.warn('Drop canceled by user in onBeforeDrop event');
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
624
|
+
return true;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Emit drop events based on operation type
|
|
628
|
+
*/
|
|
629
|
+
emitDropEvents(node, previousParent, currentParent, previousIndex, currentIndex, isReorder) {
|
|
630
|
+
const dropEvent = {
|
|
631
|
+
component: this,
|
|
632
|
+
node,
|
|
633
|
+
previousParent,
|
|
634
|
+
currentParent,
|
|
635
|
+
previousIndex,
|
|
636
|
+
currentIndex,
|
|
637
|
+
};
|
|
638
|
+
if (isReorder) {
|
|
639
|
+
this.onOrderChange.emit(dropEvent);
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
this.onMoveChange.emit(dropEvent);
|
|
643
|
+
}
|
|
644
|
+
this.onItemsChange.emit(dropEvent);
|
|
645
|
+
}
|
|
646
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXTree2Component, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
647
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXTree2Component, isStandalone: true, selector: "ax-tree2", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: true, transformFunction: null }, showCheckbox: { classPropertyName: "showCheckbox", publicName: "showCheckbox", isSignal: true, isRequired: false, transformFunction: null }, dragMode: { classPropertyName: "dragMode", publicName: "dragMode", isSignal: true, isRequired: false, transformFunction: null }, dragOperationType: { classPropertyName: "dragOperationType", publicName: "dragOperationType", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, showChildrenBadge: { classPropertyName: "showChildrenBadge", publicName: "showChildrenBadge", isSignal: true, isRequired: false, transformFunction: null }, expandedIcon: { classPropertyName: "expandedIcon", publicName: "expandedIcon", isSignal: true, isRequired: false, transformFunction: null }, collapsedIcon: { classPropertyName: "collapsedIcon", publicName: "collapsedIcon", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, nodeHeight: { classPropertyName: "nodeHeight", publicName: "nodeHeight", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null }, lazyLoad: { classPropertyName: "lazyLoad", publicName: "lazyLoad", isSignal: true, isRequired: false, transformFunction: null }, enableLazyLoad: { classPropertyName: "enableLazyLoad", publicName: "enableLazyLoad", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodes: "nodesChange", onBeforeDrop: "onBeforeDrop", onNodeToggle: "onNodeToggle", onNodeSelect: "onNodeSelect", onOrderChange: "onOrderChange", onMoveChange: "onMoveChange", onItemsChange: "onItemsChange" }, host: { properties: { "class.ax-tree2-default": "look() === 'default'", "class.ax-tree2-card": "look() === 'card'", "class.ax-tree2-with-line": "look() === 'with-line'", "style.--ax-tree-indent-size": "indentSize() + 'px'", "style.--ax-tree-line-offset": "(indentSize() / 2) + 'px'" }, classAttribute: "ax-tree2" }, ngImport: i0, template: "<!-- Root drop list -->\n<div\n [axDropList]=\"dragMode() !== 'none'\"\n [sortingDisabled]=\"false\"\n [id]=\"getListId()\"\n [attr.data-node-id]=\"null\"\n dropListGroup=\"ax-tree-nodes\"\n (dropListDropped)=\"onDrop($event)\"\n class=\"ax-tree2-drop-list\"\n [class.ax-tree2-card]=\"look() === 'card'\"\n [class.ax-tree2-with-lines]=\"look() === 'with-line'\"\n [class.ax-tree2-compact]=\"nodeHeight() === 'compact'\"\n [class.ax-tree2-comfortable]=\"nodeHeight() === 'comfortable'\"\n>\n @for (node of nodes(); track node.id) {\n @if (node.visible !== false) {\n <div\n [axDrag]=\"dragMode() !== 'none'\"\n [dragDisabled]=\"node.disabled\"\n [dragData]=\"node\"\n class=\"ax-tree2-node\"\n [class.ax-tree2-node-selected]=\"node.selected\"\n [class.ax-tree2-node-disabled]=\"node.disabled\"\n [class.ax-tree2-node-loading]=\"node.loading\"\n >\n <div\n class=\"ax-tree2-node-content\"\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"'ax-tree-node-drop-' + node.id\"\n [attr.data-node-id]=\"node.id\"\n [attr.data-drop-type]=\"'onto-node'\"\n dropListGroup=\"ax-tree-nodes\"\n (dropListDropped)=\"onDropOntoNode($event, node)\"\n >\n @if (dragMode() === 'handler') {\n <span class=\"ax-tree2-drag-handle\" axDragHandle title=\"Drag to reorder\"> \u22EE\u22EE </span>\n }\n <ax-button\n class=\"ax-tree2-expand-toggle ax-sm\"\n (onClick)=\"toggleNode(node, $any($event))\"\n [class.ax-tree2-has-children]=\"shouldShowExpandToggle(node)\"\n [class.ax-tree2-expanded]=\"node.expanded\"\n [disabled]=\"node.disabled || node.loading\"\n [style.visibility]=\"shouldShowExpandToggle(node) ? 'visible' : 'hidden'\"\n >\n @if (node.loading) {\n <ax-icon>\n <i class=\"fa-solid fa-spinner fa-spin ax-tree2-loading-spinner\"></i>\n </ax-icon>\n } @else {\n <ax-icon>\n <i [class]=\"node.expanded ? expandedIcon() : collapsedIcon()\" class=\"ax-tree2-toggle-icon\"></i>\n </ax-icon>\n }\n </ax-button>\n @if (itemTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()!\"\n [ngTemplateOutletContext]=\"getTemplateContext(node, 0)\"\n ></ng-container>\n } @else {\n @if (showCheckbox()) {\n <ax-check-box\n class=\"ax-tree2-checkbox\"\n [ngModel]=\"node.indeterminate ? null : node.selected || false\"\n [indeterminate]=\"node.indeterminate || false\"\n (onValueChanged)=\"toggleSelection(node, $event)\"\n (click)=\"$event.stopPropagation()\"\n (pointerdown)=\"$event.stopPropagation()\"\n ></ax-check-box>\n }\n @if (showIcons() && node.icon) {\n <i [class]=\"node.icon\" class=\"ax-tree2-node-icon\"></i>\n }\n <span class=\"ax-tree2-node-label\">{{ node.label }}</span>\n @if (showChildrenBadge() && (node.childrenCount || (node.children && node.children.length > 0))) {\n <ax-badge\n class=\"ax-tree2-children-badge\"\n [text]=\"(node.childrenCount ?? node.children?.length ?? 0).toString()\"\n ></ax-badge>\n }\n }\n </div>\n </div>\n @if (node.expanded && node.children && node.children.length > 0) {\n <div class=\"ax-tree2-children\">\n <ng-container\n [ngTemplateOutlet]=\"childrenList\"\n [ngTemplateOutletContext]=\"{ children: node.children, parent: node, level: 1 }\"\n ></ng-container>\n </div>\n }\n }\n }\n</div>\n\n<!-- Recursive children template -->\n<ng-template #childrenList let-children=\"children\" let-parent=\"parent\" let-level=\"level\">\n <div\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"getListId(parent)\"\n [attr.data-node-id]=\"parent.id\"\n dropListGroup=\"ax-tree-nodes\"\n (dropListDropped)=\"onDrop($event, parent)\"\n class=\"ax-tree2-drop-list\"\n >\n @for (node of children; track node.id) {\n @if (node.visible !== false) {\n <div\n [axDrag]=\"dragMode() !== 'none'\"\n [dragDisabled]=\"node.disabled\"\n [dragData]=\"node\"\n class=\"ax-tree2-node\"\n [class.ax-tree2-node-selected]=\"node.selected\"\n [class.ax-tree2-node-disabled]=\"node.disabled\"\n [class.ax-tree2-node-loading]=\"node.loading\"\n >\n <div\n class=\"ax-tree2-node-content\"\n [style.padding-left.px]=\"(level * indentSize()) / (look() === 'with-line' ? 3 : 1)\"\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"'ax-tree-node-drop-' + node.id\"\n [attr.data-node-id]=\"node.id\"\n [attr.data-drop-type]=\"'onto-node'\"\n dropListGroup=\"ax-tree-nodes\"\n (dropListDropped)=\"onDropOntoNode($event, node)\"\n >\n @if (dragMode() === 'handler') {\n <span class=\"ax-tree2-drag-handle\" axDragHandle title=\"Drag to reorder\"> \u22EE\u22EE </span>\n }\n <ax-button\n class=\"ax-tree2-expand-toggle ax-sm\"\n (onClick)=\"toggleNode(node, $any($event))\"\n [class.ax-tree2-has-children]=\"shouldShowExpandToggle(node)\"\n [class.ax-tree2-expanded]=\"node.expanded\"\n [disabled]=\"node.disabled || node.loading\"\n [style.visibility]=\"shouldShowExpandToggle(node) ? 'visible' : 'hidden'\"\n >\n @if (node.loading) {\n <ax-icon>\n <i class=\"fa-solid fa-spinner fa-spin ax-tree2-loading-spinner\"></i>\n </ax-icon>\n } @else {\n <ax-icon>\n <i [class]=\"node.expanded ? expandedIcon() : collapsedIcon()\" class=\"ax-tree2-toggle-icon\"></i>\n </ax-icon>\n }\n </ax-button>\n\n @if (itemTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()!\"\n [ngTemplateOutletContext]=\"getTemplateContext(node, level)\"\n ></ng-container>\n } @else {\n @if (showCheckbox()) {\n <ax-check-box\n class=\"ax-tree2-checkbox\"\n [ngModel]=\"node.indeterminate ? null : node.selected || false\"\n [indeterminate]=\"node.indeterminate || false\"\n (onValueChanged)=\"toggleSelection(node, $event)\"\n (click)=\"$event.stopPropagation()\"\n (pointerdown)=\"$event.stopPropagation()\"\n ></ax-check-box>\n }\n @if (showIcons() && node.icon) {\n <i [class]=\"node.icon\" class=\"ax-tree2-node-icon\"></i>\n }\n <span class=\"ax-tree2-node-label\">{{ node.label }}</span>\n @if (showChildrenBadge() && (node.childrenCount || (node.children && node.children.length > 0))) {\n <ax-badge\n class=\"ax-tree2-children-badge\"\n [text]=\"(node.childrenCount ?? node.children?.length ?? 0).toString()\"\n ></ax-badge>\n }\n }\n </div>\n </div>\n @if (node.expanded && node.children && node.children.length > 0) {\n <div class=\"ax-tree2-children\">\n <ng-container\n [ngTemplateOutlet]=\"childrenList\"\n [ngTemplateOutletContext]=\"{ children: node.children, parent: node, level: level + 1 }\"\n ></ng-container>\n </div>\n }\n }\n }\n </div>\n</ng-template>\n", styles: [".ax-tree2{display:block;width:100%;--ax-comp-tree2-indent-size: 12px;--ax-comp-tree2-node-hover-bg: rgba(var(--ax-sys-color-on-lightest-surface), .04);--ax-comp-tree2-node-selected-bg: rgba(var(--ax-sys-color-primary-500), .12);--ax-comp-tree2-node-border-radius: 6px;--ax-comp-tree2-node-margin: .25rem;--ax-comp-tree2-line-color: rgba(var(--ax-sys-color-on-lightest-surface), .15);--ax-comp-tree2-drag-preview-opacity: .9;--ax-comp-tree2-drag-placeholder-bg: rgba(var(--ax-sys-color-on-lightest-surface), .02);--ax-comp-tree2-drop-active-bg: rgba(var(--ax-sys-color-primary-500), .08);--ax-comp-tree2-drop-active-outline: rgba(var(--ax-sys-color-primary-500), .3)}.ax-tree2-drop-list{min-height:2rem}.ax-tree2-compact .ax-tree2-node-content{padding:.25rem .5rem;gap:.375rem;font-size:.8125rem}.ax-tree2-comfortable .ax-tree2-node-content{padding:.75rem .625rem;gap:.625rem;font-size:.9375rem}.ax-tree2-node{position:relative;margin:var(--ax-comp-tree2-node-margin) 0;border-radius:var(--ax-comp-tree2-node-border-radius);border:1px solid transparent;cursor:move}.ax-tree2-node:hover:not(.ax-dragging){background:var(--ax-comp-tree2-node-hover-bg)}.ax-tree2-node.ax-tree2-node-selected{background:var(--ax-comp-tree2-node-selected-bg);border-color:currentColor}.ax-tree2-node.ax-dragging{opacity:var(--ax-comp-tree2-drag-placeholder-opacity);cursor:grabbing!important}.ax-tree2-node.ax-drag-placeholder{background:var(--ax-comp-tree2-drag-placeholder-bg)}.ax-drag-preview{opacity:var(--ax-comp-tree2-drag-preview-opacity)!important;box-shadow:0 4px 12px rgba(var(--ax-sys-color-on-lightest-surface),.2)!important;cursor:grabbing!important;border:2px dashed currentColor!important}.ax-tree2-node-content.ax-drop-list-sorting-active{background:var(--ax-comp-tree2-drop-active-bg);border-radius:var(--ax-comp-tree2-node-border-radius);outline:2px dashed var(--ax-comp-tree2-drop-active-outline);outline-offset:-2px}.ax-tree2-node-content{display:flex;align-items:center;gap:.5rem;cursor:pointer;-webkit-user-select:none;user-select:none}.ax-tree2-drag-handle{cursor:grab;opacity:.6;padding:.25rem}.ax-tree2-drag-handle:hover{opacity:1}.ax-tree2-drag-handle:active{cursor:grabbing}.ax-tree2-expand-toggle{background:none;border:none;cursor:pointer;padding:.25rem;min-width:1.5rem;height:1.5rem}.ax-tree2-expand-toggle:not(.ax-tree2-has-children){opacity:0;pointer-events:none}.ax-tree2-toggle-icon{font-size:.75rem}.ax-tree2-node-icon{font-size:1.125rem;flex-shrink:0}.ax-tree2-node-label{flex:1;font-size:.875rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ax-tree2-children{padding-left:var(--ax-tree-indent-size, var(--ax-comp-tree2-indent-size))}.ax-tree2-node-disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.ax-tree2-node-loading{opacity:.7}.ax-tree2-card .ax-tree2-node{border:1px solid rgba(var(--ax-sys-color-border-lightest-surface),1);margin:.5rem 0}.ax-tree2-card .ax-tree2-node-content{padding:1rem}.ax-tree2-with-lines .ax-tree2-children{position:relative;padding-left:var(--ax-tree-indent-size, var(--ax-comp-tree2-indent-size))}.ax-tree2-with-lines .ax-tree2-children:before{content:\"\";position:absolute;left:var(--ax-tree-line-offset, calc(var(--ax-comp-tree2-indent-size) / 2));top:0;height:calc(100% - .875rem);width:1px;background:var(--ax-tree-line-color, var(--ax-comp-tree2-line-color))}.ax-tree2-with-lines .ax-tree2-node{position:relative}.ax-tree2-with-lines .ax-tree2-node:before{content:\"\";position:absolute;left:calc(-1 * var(--ax-tree-line-offset, calc(var(--ax-comp-tree2-indent-size) / 2)));top:60%;width:var(--ax-tree-line-offset, calc(var(--ax-comp-tree2-indent-size) / 2));height:1px;background:var(--ax-tree-line-color, var(--ax-comp-tree2-line-color))}.ax-tree2-with-lines>.ax-tree2-drop-list>.ax-tree2-node:before,.ax-tree2-with-lines>.ax-tree2-node:before{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AXDragDirective, selector: "[axDrag]", inputs: ["axDrag", "dragData", "dragDisabled", "dragTransition", "dragElementClone", "dropZoneGroup", "dragStartDelay", "dragResetOnDblClick", "dragLockAxis", "dragClonedTemplate", "dragCursor", "dragBoundary", "dragTransitionDuration"], outputs: ["dragPositionChanged"] }, { kind: "directive", type: AXDragHandleDirective, selector: "[axDragHandle]" }, { kind: "directive", type: AXDropListDirective, selector: "[axDropList]", inputs: ["axDropList", "sortingDisabled", "dropListGroup", "dropListOrientation"], outputs: ["dropListDropped"], exportAs: ["axDropList"] }, { 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: "component", type: AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "component", type: AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
648
|
+
}
|
|
649
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXTree2Component, decorators: [{
|
|
650
|
+
type: Component,
|
|
651
|
+
args: [{ selector: 'ax-tree2', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
652
|
+
CommonModule,
|
|
653
|
+
FormsModule,
|
|
654
|
+
AXDragDirective,
|
|
655
|
+
AXDragHandleDirective,
|
|
656
|
+
AXDropListDirective,
|
|
657
|
+
NgTemplateOutlet,
|
|
658
|
+
AXButtonComponent,
|
|
659
|
+
AXCheckBoxComponent,
|
|
660
|
+
AXBadgeComponent,
|
|
661
|
+
AXDecoratorIconComponent,
|
|
662
|
+
], host: {
|
|
663
|
+
class: 'ax-tree2',
|
|
664
|
+
'[class.ax-tree2-default]': "look() === 'default'",
|
|
665
|
+
'[class.ax-tree2-card]': "look() === 'card'",
|
|
666
|
+
'[class.ax-tree2-with-line]': "look() === 'with-line'",
|
|
667
|
+
'[style.--ax-tree-indent-size]': "indentSize() + 'px'",
|
|
668
|
+
'[style.--ax-tree-line-offset]': "(indentSize() / 2) + 'px'",
|
|
669
|
+
}, template: "<!-- Root drop list -->\n<div\n [axDropList]=\"dragMode() !== 'none'\"\n [sortingDisabled]=\"false\"\n [id]=\"getListId()\"\n [attr.data-node-id]=\"null\"\n dropListGroup=\"ax-tree-nodes\"\n (dropListDropped)=\"onDrop($event)\"\n class=\"ax-tree2-drop-list\"\n [class.ax-tree2-card]=\"look() === 'card'\"\n [class.ax-tree2-with-lines]=\"look() === 'with-line'\"\n [class.ax-tree2-compact]=\"nodeHeight() === 'compact'\"\n [class.ax-tree2-comfortable]=\"nodeHeight() === 'comfortable'\"\n>\n @for (node of nodes(); track node.id) {\n @if (node.visible !== false) {\n <div\n [axDrag]=\"dragMode() !== 'none'\"\n [dragDisabled]=\"node.disabled\"\n [dragData]=\"node\"\n class=\"ax-tree2-node\"\n [class.ax-tree2-node-selected]=\"node.selected\"\n [class.ax-tree2-node-disabled]=\"node.disabled\"\n [class.ax-tree2-node-loading]=\"node.loading\"\n >\n <div\n class=\"ax-tree2-node-content\"\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"'ax-tree-node-drop-' + node.id\"\n [attr.data-node-id]=\"node.id\"\n [attr.data-drop-type]=\"'onto-node'\"\n dropListGroup=\"ax-tree-nodes\"\n (dropListDropped)=\"onDropOntoNode($event, node)\"\n >\n @if (dragMode() === 'handler') {\n <span class=\"ax-tree2-drag-handle\" axDragHandle title=\"Drag to reorder\"> \u22EE\u22EE </span>\n }\n <ax-button\n class=\"ax-tree2-expand-toggle ax-sm\"\n (onClick)=\"toggleNode(node, $any($event))\"\n [class.ax-tree2-has-children]=\"shouldShowExpandToggle(node)\"\n [class.ax-tree2-expanded]=\"node.expanded\"\n [disabled]=\"node.disabled || node.loading\"\n [style.visibility]=\"shouldShowExpandToggle(node) ? 'visible' : 'hidden'\"\n >\n @if (node.loading) {\n <ax-icon>\n <i class=\"fa-solid fa-spinner fa-spin ax-tree2-loading-spinner\"></i>\n </ax-icon>\n } @else {\n <ax-icon>\n <i [class]=\"node.expanded ? expandedIcon() : collapsedIcon()\" class=\"ax-tree2-toggle-icon\"></i>\n </ax-icon>\n }\n </ax-button>\n @if (itemTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()!\"\n [ngTemplateOutletContext]=\"getTemplateContext(node, 0)\"\n ></ng-container>\n } @else {\n @if (showCheckbox()) {\n <ax-check-box\n class=\"ax-tree2-checkbox\"\n [ngModel]=\"node.indeterminate ? null : node.selected || false\"\n [indeterminate]=\"node.indeterminate || false\"\n (onValueChanged)=\"toggleSelection(node, $event)\"\n (click)=\"$event.stopPropagation()\"\n (pointerdown)=\"$event.stopPropagation()\"\n ></ax-check-box>\n }\n @if (showIcons() && node.icon) {\n <i [class]=\"node.icon\" class=\"ax-tree2-node-icon\"></i>\n }\n <span class=\"ax-tree2-node-label\">{{ node.label }}</span>\n @if (showChildrenBadge() && (node.childrenCount || (node.children && node.children.length > 0))) {\n <ax-badge\n class=\"ax-tree2-children-badge\"\n [text]=\"(node.childrenCount ?? node.children?.length ?? 0).toString()\"\n ></ax-badge>\n }\n }\n </div>\n </div>\n @if (node.expanded && node.children && node.children.length > 0) {\n <div class=\"ax-tree2-children\">\n <ng-container\n [ngTemplateOutlet]=\"childrenList\"\n [ngTemplateOutletContext]=\"{ children: node.children, parent: node, level: 1 }\"\n ></ng-container>\n </div>\n }\n }\n }\n</div>\n\n<!-- Recursive children template -->\n<ng-template #childrenList let-children=\"children\" let-parent=\"parent\" let-level=\"level\">\n <div\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"getListId(parent)\"\n [attr.data-node-id]=\"parent.id\"\n dropListGroup=\"ax-tree-nodes\"\n (dropListDropped)=\"onDrop($event, parent)\"\n class=\"ax-tree2-drop-list\"\n >\n @for (node of children; track node.id) {\n @if (node.visible !== false) {\n <div\n [axDrag]=\"dragMode() !== 'none'\"\n [dragDisabled]=\"node.disabled\"\n [dragData]=\"node\"\n class=\"ax-tree2-node\"\n [class.ax-tree2-node-selected]=\"node.selected\"\n [class.ax-tree2-node-disabled]=\"node.disabled\"\n [class.ax-tree2-node-loading]=\"node.loading\"\n >\n <div\n class=\"ax-tree2-node-content\"\n [style.padding-left.px]=\"(level * indentSize()) / (look() === 'with-line' ? 3 : 1)\"\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"'ax-tree-node-drop-' + node.id\"\n [attr.data-node-id]=\"node.id\"\n [attr.data-drop-type]=\"'onto-node'\"\n dropListGroup=\"ax-tree-nodes\"\n (dropListDropped)=\"onDropOntoNode($event, node)\"\n >\n @if (dragMode() === 'handler') {\n <span class=\"ax-tree2-drag-handle\" axDragHandle title=\"Drag to reorder\"> \u22EE\u22EE </span>\n }\n <ax-button\n class=\"ax-tree2-expand-toggle ax-sm\"\n (onClick)=\"toggleNode(node, $any($event))\"\n [class.ax-tree2-has-children]=\"shouldShowExpandToggle(node)\"\n [class.ax-tree2-expanded]=\"node.expanded\"\n [disabled]=\"node.disabled || node.loading\"\n [style.visibility]=\"shouldShowExpandToggle(node) ? 'visible' : 'hidden'\"\n >\n @if (node.loading) {\n <ax-icon>\n <i class=\"fa-solid fa-spinner fa-spin ax-tree2-loading-spinner\"></i>\n </ax-icon>\n } @else {\n <ax-icon>\n <i [class]=\"node.expanded ? expandedIcon() : collapsedIcon()\" class=\"ax-tree2-toggle-icon\"></i>\n </ax-icon>\n }\n </ax-button>\n\n @if (itemTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()!\"\n [ngTemplateOutletContext]=\"getTemplateContext(node, level)\"\n ></ng-container>\n } @else {\n @if (showCheckbox()) {\n <ax-check-box\n class=\"ax-tree2-checkbox\"\n [ngModel]=\"node.indeterminate ? null : node.selected || false\"\n [indeterminate]=\"node.indeterminate || false\"\n (onValueChanged)=\"toggleSelection(node, $event)\"\n (click)=\"$event.stopPropagation()\"\n (pointerdown)=\"$event.stopPropagation()\"\n ></ax-check-box>\n }\n @if (showIcons() && node.icon) {\n <i [class]=\"node.icon\" class=\"ax-tree2-node-icon\"></i>\n }\n <span class=\"ax-tree2-node-label\">{{ node.label }}</span>\n @if (showChildrenBadge() && (node.childrenCount || (node.children && node.children.length > 0))) {\n <ax-badge\n class=\"ax-tree2-children-badge\"\n [text]=\"(node.childrenCount ?? node.children?.length ?? 0).toString()\"\n ></ax-badge>\n }\n }\n </div>\n </div>\n @if (node.expanded && node.children && node.children.length > 0) {\n <div class=\"ax-tree2-children\">\n <ng-container\n [ngTemplateOutlet]=\"childrenList\"\n [ngTemplateOutletContext]=\"{ children: node.children, parent: node, level: level + 1 }\"\n ></ng-container>\n </div>\n }\n }\n }\n </div>\n</ng-template>\n", styles: [".ax-tree2{display:block;width:100%;--ax-comp-tree2-indent-size: 12px;--ax-comp-tree2-node-hover-bg: rgba(var(--ax-sys-color-on-lightest-surface), .04);--ax-comp-tree2-node-selected-bg: rgba(var(--ax-sys-color-primary-500), .12);--ax-comp-tree2-node-border-radius: 6px;--ax-comp-tree2-node-margin: .25rem;--ax-comp-tree2-line-color: rgba(var(--ax-sys-color-on-lightest-surface), .15);--ax-comp-tree2-drag-preview-opacity: .9;--ax-comp-tree2-drag-placeholder-bg: rgba(var(--ax-sys-color-on-lightest-surface), .02);--ax-comp-tree2-drop-active-bg: rgba(var(--ax-sys-color-primary-500), .08);--ax-comp-tree2-drop-active-outline: rgba(var(--ax-sys-color-primary-500), .3)}.ax-tree2-drop-list{min-height:2rem}.ax-tree2-compact .ax-tree2-node-content{padding:.25rem .5rem;gap:.375rem;font-size:.8125rem}.ax-tree2-comfortable .ax-tree2-node-content{padding:.75rem .625rem;gap:.625rem;font-size:.9375rem}.ax-tree2-node{position:relative;margin:var(--ax-comp-tree2-node-margin) 0;border-radius:var(--ax-comp-tree2-node-border-radius);border:1px solid transparent;cursor:move}.ax-tree2-node:hover:not(.ax-dragging){background:var(--ax-comp-tree2-node-hover-bg)}.ax-tree2-node.ax-tree2-node-selected{background:var(--ax-comp-tree2-node-selected-bg);border-color:currentColor}.ax-tree2-node.ax-dragging{opacity:var(--ax-comp-tree2-drag-placeholder-opacity);cursor:grabbing!important}.ax-tree2-node.ax-drag-placeholder{background:var(--ax-comp-tree2-drag-placeholder-bg)}.ax-drag-preview{opacity:var(--ax-comp-tree2-drag-preview-opacity)!important;box-shadow:0 4px 12px rgba(var(--ax-sys-color-on-lightest-surface),.2)!important;cursor:grabbing!important;border:2px dashed currentColor!important}.ax-tree2-node-content.ax-drop-list-sorting-active{background:var(--ax-comp-tree2-drop-active-bg);border-radius:var(--ax-comp-tree2-node-border-radius);outline:2px dashed var(--ax-comp-tree2-drop-active-outline);outline-offset:-2px}.ax-tree2-node-content{display:flex;align-items:center;gap:.5rem;cursor:pointer;-webkit-user-select:none;user-select:none}.ax-tree2-drag-handle{cursor:grab;opacity:.6;padding:.25rem}.ax-tree2-drag-handle:hover{opacity:1}.ax-tree2-drag-handle:active{cursor:grabbing}.ax-tree2-expand-toggle{background:none;border:none;cursor:pointer;padding:.25rem;min-width:1.5rem;height:1.5rem}.ax-tree2-expand-toggle:not(.ax-tree2-has-children){opacity:0;pointer-events:none}.ax-tree2-toggle-icon{font-size:.75rem}.ax-tree2-node-icon{font-size:1.125rem;flex-shrink:0}.ax-tree2-node-label{flex:1;font-size:.875rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ax-tree2-children{padding-left:var(--ax-tree-indent-size, var(--ax-comp-tree2-indent-size))}.ax-tree2-node-disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.ax-tree2-node-loading{opacity:.7}.ax-tree2-card .ax-tree2-node{border:1px solid rgba(var(--ax-sys-color-border-lightest-surface),1);margin:.5rem 0}.ax-tree2-card .ax-tree2-node-content{padding:1rem}.ax-tree2-with-lines .ax-tree2-children{position:relative;padding-left:var(--ax-tree-indent-size, var(--ax-comp-tree2-indent-size))}.ax-tree2-with-lines .ax-tree2-children:before{content:\"\";position:absolute;left:var(--ax-tree-line-offset, calc(var(--ax-comp-tree2-indent-size) / 2));top:0;height:calc(100% - .875rem);width:1px;background:var(--ax-tree-line-color, var(--ax-comp-tree2-line-color))}.ax-tree2-with-lines .ax-tree2-node{position:relative}.ax-tree2-with-lines .ax-tree2-node:before{content:\"\";position:absolute;left:calc(-1 * var(--ax-tree-line-offset, calc(var(--ax-comp-tree2-indent-size) / 2)));top:60%;width:var(--ax-tree-line-offset, calc(var(--ax-comp-tree2-indent-size) / 2));height:1px;background:var(--ax-tree-line-color, var(--ax-comp-tree2-line-color))}.ax-tree2-with-lines>.ax-tree2-drop-list>.ax-tree2-node:before,.ax-tree2-with-lines>.ax-tree2-node:before{display:none}\n"] }]
|
|
670
|
+
}], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: true }] }, { type: i0.Output, args: ["nodesChange"] }], showCheckbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCheckbox", required: false }] }], dragMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragMode", required: false }] }], dragOperationType: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragOperationType", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], showChildrenBadge: [{ type: i0.Input, args: [{ isSignal: true, alias: "showChildrenBadge", required: false }] }], expandedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedIcon", required: false }] }], collapsedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsedIcon", required: false }] }], indentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "indentSize", required: false }] }], nodeHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeHeight", required: false }] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }], itemTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemTemplate", required: false }] }], lazyLoad: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazyLoad", required: false }] }], enableLazyLoad: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableLazyLoad", required: false }] }], onBeforeDrop: [{ type: i0.Output, args: ["onBeforeDrop"] }], onNodeToggle: [{ type: i0.Output, args: ["onNodeToggle"] }], onNodeSelect: [{ type: i0.Output, args: ["onNodeSelect"] }], onOrderChange: [{ type: i0.Output, args: ["onOrderChange"] }], onMoveChange: [{ type: i0.Output, args: ["onMoveChange"] }], onItemsChange: [{ type: i0.Output, args: ["onItemsChange"] }] } });
|
|
671
|
+
|
|
672
|
+
class Tree2Module {
|
|
673
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: Tree2Module, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
674
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.12", ngImport: i0, type: Tree2Module, imports: [AXTree2Component] }); }
|
|
675
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: Tree2Module, imports: [AXTree2Component] }); }
|
|
676
|
+
}
|
|
677
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: Tree2Module, decorators: [{
|
|
678
|
+
type: NgModule,
|
|
679
|
+
args: [{
|
|
680
|
+
imports: [AXTree2Component],
|
|
681
|
+
}]
|
|
682
|
+
}] });
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Generated bundle index. Do not edit.
|
|
686
|
+
*/
|
|
687
|
+
|
|
688
|
+
export { AXTree2Component, Tree2Module };
|
|
689
|
+
//# sourceMappingURL=acorex-components-tree2.mjs.map
|