@memberjunction/ng-trees 6.1.4 → 6.2.0-edge.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/models/tree-types.d.ts +6 -0
- package/dist/lib/models/tree-types.d.ts.map +1 -1
- package/dist/lib/models/tree-types.js +15 -3
- package/dist/lib/models/tree-types.js.map +1 -1
- package/dist/lib/tree/tree.component.d.ts +16 -0
- package/dist/lib/tree/tree.component.d.ts.map +1 -1
- package/dist/lib/tree/tree.component.js +46 -14
- package/dist/lib/tree/tree.component.js.map +1 -1
- package/dist/lib/tree-dropdown/tree-dropdown.component.d.ts +54 -4
- package/dist/lib/tree-dropdown/tree-dropdown.component.d.ts.map +1 -1
- package/dist/lib/tree-dropdown/tree-dropdown.component.js +169 -69
- package/dist/lib/tree-dropdown/tree-dropdown.component.js.map +1 -1
- package/package.json +7 -7
|
@@ -142,7 +142,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
142
142
|
if (!CompositeKey.EqualsEx(val, this._value)) {
|
|
143
143
|
this._value = val;
|
|
144
144
|
// If tree is loaded, sync selection immediately
|
|
145
|
-
if (this.IsLoaded && this.
|
|
145
|
+
if (this.IsLoaded && this.TreeComponent) {
|
|
146
146
|
this.syncValueToSelection();
|
|
147
147
|
}
|
|
148
148
|
else {
|
|
@@ -200,10 +200,42 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
200
200
|
// ========================================
|
|
201
201
|
// ViewChild References
|
|
202
202
|
// ========================================
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
203
|
+
TriggerElement;
|
|
204
|
+
/** @deprecated Use {@link TriggerElement}. */
|
|
205
|
+
get triggerElement() {
|
|
206
|
+
return this.TriggerElement;
|
|
207
|
+
}
|
|
208
|
+
/** @deprecated Use {@link TriggerElement}. */
|
|
209
|
+
set triggerElement(value) {
|
|
210
|
+
this.TriggerElement = value;
|
|
211
|
+
}
|
|
212
|
+
SearchInput;
|
|
213
|
+
/** @deprecated Use {@link SearchInput}. */
|
|
214
|
+
get searchInput() {
|
|
215
|
+
return this.SearchInput;
|
|
216
|
+
}
|
|
217
|
+
/** @deprecated Use {@link SearchInput}. */
|
|
218
|
+
set searchInput(value) {
|
|
219
|
+
this.SearchInput = value;
|
|
220
|
+
}
|
|
221
|
+
DropdownPanel;
|
|
222
|
+
/** @deprecated Use {@link DropdownPanel}. */
|
|
223
|
+
get dropdownPanel() {
|
|
224
|
+
return this.DropdownPanel;
|
|
225
|
+
}
|
|
226
|
+
/** @deprecated Use {@link DropdownPanel}. */
|
|
227
|
+
set dropdownPanel(value) {
|
|
228
|
+
this.DropdownPanel = value;
|
|
229
|
+
}
|
|
230
|
+
TreeComponent;
|
|
231
|
+
/** @deprecated Use {@link TreeComponent}. */
|
|
232
|
+
get treeComponent() {
|
|
233
|
+
return this.TreeComponent;
|
|
234
|
+
}
|
|
235
|
+
/** @deprecated Use {@link TreeComponent}. */
|
|
236
|
+
set treeComponent(value) {
|
|
237
|
+
this.TreeComponent = value;
|
|
238
|
+
}
|
|
207
239
|
// ========================================
|
|
208
240
|
// State
|
|
209
241
|
// ========================================
|
|
@@ -361,8 +393,8 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
361
393
|
this.SelectedNodes = [];
|
|
362
394
|
this._value = null;
|
|
363
395
|
this._pendingDisplayText = null;
|
|
364
|
-
if (this.
|
|
365
|
-
this.
|
|
396
|
+
if (this.TreeComponent) {
|
|
397
|
+
this.TreeComponent.ClearSelection();
|
|
366
398
|
}
|
|
367
399
|
this.ValueChange.emit(this._value);
|
|
368
400
|
this.SelectionChange.emit(null);
|
|
@@ -372,8 +404,8 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
372
404
|
* Refresh tree data
|
|
373
405
|
*/
|
|
374
406
|
async Refresh() {
|
|
375
|
-
if (this.
|
|
376
|
-
await this.
|
|
407
|
+
if (this.TreeComponent) {
|
|
408
|
+
await this.TreeComponent.Refresh();
|
|
377
409
|
}
|
|
378
410
|
}
|
|
379
411
|
// ========================================
|
|
@@ -382,15 +414,19 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
382
414
|
/**
|
|
383
415
|
* Handle trigger click
|
|
384
416
|
*/
|
|
385
|
-
|
|
417
|
+
OnTriggerClick() {
|
|
386
418
|
if (!this.Disabled) {
|
|
387
419
|
this.Toggle();
|
|
388
420
|
}
|
|
389
421
|
}
|
|
422
|
+
/** @deprecated Use {@link OnTriggerClick}. */
|
|
423
|
+
onTriggerClick() {
|
|
424
|
+
return this.OnTriggerClick();
|
|
425
|
+
}
|
|
390
426
|
/**
|
|
391
427
|
* Handle trigger keydown
|
|
392
428
|
*/
|
|
393
|
-
|
|
429
|
+
OnTriggerKeyDown(event) {
|
|
394
430
|
if (this.Disabled) {
|
|
395
431
|
return;
|
|
396
432
|
}
|
|
@@ -409,20 +445,28 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
409
445
|
break;
|
|
410
446
|
}
|
|
411
447
|
}
|
|
448
|
+
/** @deprecated Use {@link OnTriggerKeyDown}. */
|
|
449
|
+
onTriggerKeyDown(event) {
|
|
450
|
+
return this.OnTriggerKeyDown(event);
|
|
451
|
+
}
|
|
412
452
|
/**
|
|
413
453
|
* Handle search input
|
|
414
454
|
*/
|
|
415
|
-
|
|
455
|
+
OnSearchInput(event) {
|
|
416
456
|
const value = event.target.value;
|
|
417
457
|
this.SearchText = value;
|
|
418
458
|
this.searchSubject.next(value);
|
|
419
459
|
}
|
|
460
|
+
/** @deprecated Use {@link OnSearchInput}. */
|
|
461
|
+
onSearchInput(event) {
|
|
462
|
+
return this.OnSearchInput(event);
|
|
463
|
+
}
|
|
420
464
|
/**
|
|
421
465
|
* Handle search keydown — provides full keyboard navigation while search input retains focus.
|
|
422
466
|
* The tree's own keyboard handler doesn't fire because the search input has DOM focus,
|
|
423
467
|
* so all navigation is handled here by manipulating the tree's FocusedNode visual state.
|
|
424
468
|
*/
|
|
425
|
-
|
|
469
|
+
OnSearchKeyDown(event) {
|
|
426
470
|
switch (event.key) {
|
|
427
471
|
case 'Escape':
|
|
428
472
|
event.preventDefault();
|
|
@@ -459,20 +503,28 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
459
503
|
break;
|
|
460
504
|
}
|
|
461
505
|
}
|
|
506
|
+
/** @deprecated Use {@link OnSearchKeyDown}. */
|
|
507
|
+
onSearchKeyDown(event) {
|
|
508
|
+
return this.OnSearchKeyDown(event);
|
|
509
|
+
}
|
|
462
510
|
/**
|
|
463
511
|
* Handle clear search
|
|
464
512
|
*/
|
|
465
|
-
|
|
513
|
+
OnClearSearch() {
|
|
466
514
|
this.SearchText = '';
|
|
467
515
|
this.clearSearch();
|
|
468
|
-
if (this.
|
|
469
|
-
this.
|
|
516
|
+
if (this.SearchInput) {
|
|
517
|
+
this.SearchInput.nativeElement.focus();
|
|
470
518
|
}
|
|
471
519
|
}
|
|
520
|
+
/** @deprecated Use {@link OnClearSearch}. */
|
|
521
|
+
onClearSearch() {
|
|
522
|
+
return this.OnClearSearch();
|
|
523
|
+
}
|
|
472
524
|
/**
|
|
473
525
|
* Handle tree selection change
|
|
474
526
|
*/
|
|
475
|
-
|
|
527
|
+
OnTreeSelectionChange(nodes) {
|
|
476
528
|
this.SelectedNodes = nodes;
|
|
477
529
|
// Clear pending display text since we now have real nodes
|
|
478
530
|
this._pendingDisplayText = null;
|
|
@@ -494,6 +546,10 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
494
546
|
}
|
|
495
547
|
this.cdr.detectChanges();
|
|
496
548
|
}
|
|
549
|
+
/** @deprecated Use {@link OnTreeSelectionChange}. */
|
|
550
|
+
onTreeSelectionChange(nodes) {
|
|
551
|
+
return this.OnTreeSelectionChange(nodes);
|
|
552
|
+
}
|
|
497
553
|
/**
|
|
498
554
|
* Build the CompositeKey for a selected node. A node's `ID` is the value of its config's `IDField`
|
|
499
555
|
* (leaf or branch), so the key is named after that field rather than a hardcoded `ID`. When no
|
|
@@ -519,12 +575,16 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
519
575
|
/**
|
|
520
576
|
* Handle tree data load events
|
|
521
577
|
*/
|
|
522
|
-
|
|
578
|
+
OnTreeBeforeDataLoad(event) {
|
|
523
579
|
this.IsLoading = true;
|
|
524
580
|
this.BeforeDataLoad.emit(event);
|
|
525
581
|
this.cdr.detectChanges();
|
|
526
582
|
}
|
|
527
|
-
|
|
583
|
+
/** @deprecated Use {@link OnTreeBeforeDataLoad}. */
|
|
584
|
+
onTreeBeforeDataLoad(event) {
|
|
585
|
+
return this.OnTreeBeforeDataLoad(event);
|
|
586
|
+
}
|
|
587
|
+
OnTreeAfterDataLoad(event) {
|
|
528
588
|
this.IsLoading = false;
|
|
529
589
|
this.IsLoaded = true;
|
|
530
590
|
// Resolve all pending WaitForDataLoad() promises
|
|
@@ -535,7 +595,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
535
595
|
}
|
|
536
596
|
// Sync selection after load - defer to next microtask to ensure ViewChild is resolved
|
|
537
597
|
Promise.resolve().then(() => {
|
|
538
|
-
if (this.
|
|
598
|
+
if (this.TreeComponent) {
|
|
539
599
|
}
|
|
540
600
|
this.syncValueToSelection();
|
|
541
601
|
this.cdr.detectChanges();
|
|
@@ -543,15 +603,27 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
543
603
|
this.AfterDataLoad.emit(event);
|
|
544
604
|
this.cdr.detectChanges();
|
|
545
605
|
}
|
|
606
|
+
/** @deprecated Use {@link OnTreeAfterDataLoad}. */
|
|
607
|
+
onTreeAfterDataLoad(event) {
|
|
608
|
+
return this.OnTreeAfterDataLoad(event);
|
|
609
|
+
}
|
|
546
610
|
/**
|
|
547
611
|
* Bubble tree events
|
|
548
612
|
*/
|
|
549
|
-
|
|
613
|
+
OnTreeBeforeNodeSelect(event) {
|
|
550
614
|
this.BeforeNodeSelect.emit(event);
|
|
551
615
|
}
|
|
552
|
-
|
|
616
|
+
/** @deprecated Use {@link OnTreeBeforeNodeSelect}. */
|
|
617
|
+
onTreeBeforeNodeSelect(event) {
|
|
618
|
+
return this.OnTreeBeforeNodeSelect(event);
|
|
619
|
+
}
|
|
620
|
+
OnTreeAfterNodeSelect(event) {
|
|
553
621
|
this.AfterNodeSelect.emit(event);
|
|
554
622
|
}
|
|
623
|
+
/** @deprecated Use {@link OnTreeAfterNodeSelect}. */
|
|
624
|
+
onTreeAfterNodeSelect(event) {
|
|
625
|
+
return this.OnTreeAfterNodeSelect(event);
|
|
626
|
+
}
|
|
555
627
|
// ========================================
|
|
556
628
|
// Keyboard Navigation Helpers
|
|
557
629
|
// ========================================
|
|
@@ -567,12 +639,12 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
567
639
|
return;
|
|
568
640
|
const tryFocus = (retriesLeft) => {
|
|
569
641
|
// Try ViewChild first
|
|
570
|
-
if (this.
|
|
571
|
-
this.
|
|
642
|
+
if (this.SearchInput?.nativeElement) {
|
|
643
|
+
this.SearchInput.nativeElement.focus();
|
|
572
644
|
return;
|
|
573
645
|
}
|
|
574
646
|
// Fallback: query DOM directly (ViewChild may not resolve for @if blocks)
|
|
575
|
-
const panel = this.
|
|
647
|
+
const panel = this.DropdownPanel?.nativeElement;
|
|
576
648
|
if (panel) {
|
|
577
649
|
const input = panel.querySelector('.tree-dropdown-search__input');
|
|
578
650
|
if (input) {
|
|
@@ -593,13 +665,13 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
593
665
|
* Navigate tree focus up/down/first/last while search input retains DOM focus
|
|
594
666
|
*/
|
|
595
667
|
navigateTree(direction) {
|
|
596
|
-
if (!this.
|
|
668
|
+
if (!this.TreeComponent?.Nodes?.length)
|
|
597
669
|
return;
|
|
598
|
-
const visibleNodes = this.getVisibleNodesInOrder(this.
|
|
670
|
+
const visibleNodes = this.getVisibleNodesInOrder(this.TreeComponent.Nodes);
|
|
599
671
|
if (visibleNodes.length === 0)
|
|
600
672
|
return;
|
|
601
|
-
const currentIndex = this.
|
|
602
|
-
? visibleNodes.indexOf(this.
|
|
673
|
+
const currentIndex = this.TreeComponent.FocusedNode
|
|
674
|
+
? visibleNodes.indexOf(this.TreeComponent.FocusedNode)
|
|
603
675
|
: -1;
|
|
604
676
|
let targetNode = null;
|
|
605
677
|
switch (direction) {
|
|
@@ -625,7 +697,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
625
697
|
break;
|
|
626
698
|
}
|
|
627
699
|
if (targetNode) {
|
|
628
|
-
this.
|
|
700
|
+
this.TreeComponent.FocusedNode = targetNode;
|
|
629
701
|
this.cdr.detectChanges();
|
|
630
702
|
this.scrollFocusedNodeIntoView();
|
|
631
703
|
}
|
|
@@ -634,7 +706,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
634
706
|
* Select the currently focused tree node (Enter key)
|
|
635
707
|
*/
|
|
636
708
|
selectFocusedNode() {
|
|
637
|
-
const focusedNode = this.
|
|
709
|
+
const focusedNode = this.TreeComponent?.FocusedNode;
|
|
638
710
|
if (!focusedNode)
|
|
639
711
|
return;
|
|
640
712
|
// Check if the node type is selectable per config
|
|
@@ -642,7 +714,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
642
714
|
|| (this.SelectableTypes === 'leaf' && focusedNode.Type === 'leaf')
|
|
643
715
|
|| (this.SelectableTypes === 'branch' && focusedNode.Type === 'branch');
|
|
644
716
|
if (isSelectable) {
|
|
645
|
-
this.
|
|
717
|
+
this.TreeComponent.SelectNodes([focusedNode.ID], true);
|
|
646
718
|
}
|
|
647
719
|
else if (focusedNode.Type === 'branch') {
|
|
648
720
|
// Non-selectable branch: toggle expand/collapse
|
|
@@ -653,18 +725,18 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
653
725
|
* ArrowRight: expand focused branch or descend to first child
|
|
654
726
|
*/
|
|
655
727
|
expandOrDescendFocusedNode() {
|
|
656
|
-
const node = this.
|
|
728
|
+
const node = this.TreeComponent?.FocusedNode;
|
|
657
729
|
if (!node || node.Type !== 'branch')
|
|
658
730
|
return;
|
|
659
731
|
if (!node.Expanded && node.Children?.length) {
|
|
660
|
-
this.
|
|
732
|
+
this.TreeComponent.ExpandToNode(node.Children[0].ID);
|
|
661
733
|
this.cdr.detectChanges();
|
|
662
734
|
}
|
|
663
735
|
else if (node.Expanded && node.Children?.length) {
|
|
664
736
|
// Already expanded: move focus to first visible child
|
|
665
737
|
const firstVisible = node.Children.find(c => c.Visible);
|
|
666
738
|
if (firstVisible) {
|
|
667
|
-
this.
|
|
739
|
+
this.TreeComponent.FocusedNode = firstVisible;
|
|
668
740
|
this.cdr.detectChanges();
|
|
669
741
|
this.scrollFocusedNodeIntoView();
|
|
670
742
|
}
|
|
@@ -674,7 +746,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
674
746
|
* ArrowLeft: collapse focused branch or ascend to parent
|
|
675
747
|
*/
|
|
676
748
|
collapseOrAscendFocusedNode() {
|
|
677
|
-
const node = this.
|
|
749
|
+
const node = this.TreeComponent?.FocusedNode;
|
|
678
750
|
if (!node)
|
|
679
751
|
return;
|
|
680
752
|
if (node.Type === 'branch' && node.Expanded) {
|
|
@@ -683,10 +755,10 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
683
755
|
}
|
|
684
756
|
else if (node.ParentID) {
|
|
685
757
|
// Move to parent
|
|
686
|
-
const allNodes = this.getVisibleNodesInOrder(this.
|
|
758
|
+
const allNodes = this.getVisibleNodesInOrder(this.TreeComponent.Nodes);
|
|
687
759
|
const parent = allNodes.find(n => UUIDsEqual(n.ID, node.ParentID));
|
|
688
760
|
if (parent) {
|
|
689
|
-
this.
|
|
761
|
+
this.TreeComponent.FocusedNode = parent;
|
|
690
762
|
this.cdr.detectChanges();
|
|
691
763
|
this.scrollFocusedNodeIntoView();
|
|
692
764
|
}
|
|
@@ -700,7 +772,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
700
772
|
node.Expanded = false;
|
|
701
773
|
}
|
|
702
774
|
else {
|
|
703
|
-
this.
|
|
775
|
+
this.TreeComponent.ExpandToNode(node.ID);
|
|
704
776
|
}
|
|
705
777
|
this.cdr.detectChanges();
|
|
706
778
|
}
|
|
@@ -709,7 +781,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
709
781
|
*/
|
|
710
782
|
scrollFocusedNodeIntoView() {
|
|
711
783
|
requestAnimationFrame(() => {
|
|
712
|
-
const panel = this.
|
|
784
|
+
const panel = this.DropdownPanel?.nativeElement;
|
|
713
785
|
if (!panel)
|
|
714
786
|
return;
|
|
715
787
|
const focused = panel.querySelector('.tree-node-focused, .tree-node--focused, [data-focused="true"]');
|
|
@@ -745,10 +817,10 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
745
817
|
* Calculate dropdown position
|
|
746
818
|
*/
|
|
747
819
|
calculatePosition() {
|
|
748
|
-
if (!this.
|
|
820
|
+
if (!this.TriggerElement) {
|
|
749
821
|
return;
|
|
750
822
|
}
|
|
751
|
-
const triggerRect = this.
|
|
823
|
+
const triggerRect = this.TriggerElement.nativeElement.getBoundingClientRect();
|
|
752
824
|
const viewportHeight = window.innerHeight;
|
|
753
825
|
const viewportWidth = window.innerWidth;
|
|
754
826
|
// Parse max height from config
|
|
@@ -832,9 +904,9 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
832
904
|
if (!this.IsOpen) {
|
|
833
905
|
return;
|
|
834
906
|
}
|
|
835
|
-
const isInsideTrigger = this.
|
|
907
|
+
const isInsideTrigger = this.TriggerElement?.nativeElement?.contains(target);
|
|
836
908
|
// Check if click is inside the dropdown panel (rendered inline, not in portal)
|
|
837
|
-
const isInsideDropdown = this.
|
|
909
|
+
const isInsideDropdown = this.DropdownPanel?.nativeElement?.contains(target);
|
|
838
910
|
if (!isInsideTrigger && !isInsideDropdown) {
|
|
839
911
|
this.Close('outsideClick');
|
|
840
912
|
}
|
|
@@ -913,10 +985,10 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
913
985
|
}
|
|
914
986
|
const searchText = beforeEvent.ModifiedSearchText ?? text;
|
|
915
987
|
// Guard: tree component may not be ready or may have no nodes loaded
|
|
916
|
-
if (!this.
|
|
988
|
+
if (!this.TreeComponent || !this.IsLoaded) {
|
|
917
989
|
return;
|
|
918
990
|
}
|
|
919
|
-
const matchedNodes = this.
|
|
991
|
+
const matchedNodes = this.TreeComponent.FilterNodes(searchText, {
|
|
920
992
|
caseSensitive: this.SearchConfig.CaseSensitive,
|
|
921
993
|
searchBranches: this.SearchConfig.SearchBranches ?? true,
|
|
922
994
|
searchLeaves: this.SearchConfig.SearchLeaves ?? true,
|
|
@@ -925,7 +997,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
925
997
|
// Auto-expand to show matches — guard against empty results
|
|
926
998
|
if (matchedNodes.length > 0 && this.SearchConfig.AutoExpandMatches !== false && searchText.trim()) {
|
|
927
999
|
for (const node of matchedNodes) {
|
|
928
|
-
this.
|
|
1000
|
+
this.TreeComponent.ExpandToNode(node.ID);
|
|
929
1001
|
}
|
|
930
1002
|
}
|
|
931
1003
|
// Fire after event
|
|
@@ -937,8 +1009,8 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
937
1009
|
* Clear search filter
|
|
938
1010
|
*/
|
|
939
1011
|
clearSearch() {
|
|
940
|
-
if (this.
|
|
941
|
-
this.
|
|
1012
|
+
if (this.TreeComponent?.Nodes?.length) {
|
|
1013
|
+
this.TreeComponent.FilterNodes('', {});
|
|
942
1014
|
this.cdr.detectChanges();
|
|
943
1015
|
}
|
|
944
1016
|
}
|
|
@@ -968,17 +1040,17 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
968
1040
|
* Sync value to tree selection
|
|
969
1041
|
*/
|
|
970
1042
|
syncValueToSelection() {
|
|
971
|
-
if (!this.
|
|
1043
|
+
if (!this.TreeComponent || !this.IsLoaded) {
|
|
972
1044
|
return;
|
|
973
1045
|
}
|
|
974
1046
|
// Convert CompositeKey(s) to string IDs for tree selection
|
|
975
|
-
const ids = this.
|
|
1047
|
+
const ids = this.GetSelectedIDsArray();
|
|
976
1048
|
// Pass emitChange=false to avoid emitting SelectionChange during sync
|
|
977
1049
|
// This prevents unnecessary events and parent component confusion
|
|
978
|
-
this.
|
|
1050
|
+
this.TreeComponent.SelectNodes(ids, false);
|
|
979
1051
|
// Use try-catch as defensive measure since tree component may not be fully ready
|
|
980
1052
|
try {
|
|
981
|
-
this.SelectedNodes = this.
|
|
1053
|
+
this.SelectedNodes = this.TreeComponent.GetSelectedNodes() || [];
|
|
982
1054
|
}
|
|
983
1055
|
catch {
|
|
984
1056
|
this.SelectedNodes = [];
|
|
@@ -1030,7 +1102,7 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
1030
1102
|
/**
|
|
1031
1103
|
* Get display text for selected value(s)
|
|
1032
1104
|
*/
|
|
1033
|
-
|
|
1105
|
+
GetDisplayText() {
|
|
1034
1106
|
// If we have selected nodes from the tree, use those
|
|
1035
1107
|
if (this.SelectedNodes.length > 0) {
|
|
1036
1108
|
if (this.SelectionMode === 'single') {
|
|
@@ -1048,34 +1120,50 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
1048
1120
|
}
|
|
1049
1121
|
return '';
|
|
1050
1122
|
}
|
|
1123
|
+
/** @deprecated Use {@link GetDisplayText}. */
|
|
1124
|
+
getDisplayText() {
|
|
1125
|
+
return this.GetDisplayText();
|
|
1126
|
+
}
|
|
1051
1127
|
/**
|
|
1052
1128
|
* Get display icon for single selection
|
|
1053
1129
|
*/
|
|
1054
|
-
|
|
1130
|
+
GetDisplayIcon() {
|
|
1055
1131
|
if (!this.ShowIconInDisplay || this.SelectedNodes.length !== 1) {
|
|
1056
1132
|
return null;
|
|
1057
1133
|
}
|
|
1058
1134
|
return this.SelectedNodes[0].Icon;
|
|
1059
1135
|
}
|
|
1136
|
+
/** @deprecated Use {@link GetDisplayIcon}. */
|
|
1137
|
+
getDisplayIcon() {
|
|
1138
|
+
return this.GetDisplayIcon();
|
|
1139
|
+
}
|
|
1060
1140
|
/**
|
|
1061
1141
|
* Get display color for single selection
|
|
1062
1142
|
*/
|
|
1063
|
-
|
|
1143
|
+
GetDisplayColor() {
|
|
1064
1144
|
if (this.SelectedNodes.length !== 1) {
|
|
1065
1145
|
return null;
|
|
1066
1146
|
}
|
|
1067
1147
|
return this.SelectedNodes[0].Color || null;
|
|
1068
1148
|
}
|
|
1149
|
+
/** @deprecated Use {@link GetDisplayColor}. */
|
|
1150
|
+
getDisplayColor() {
|
|
1151
|
+
return this.GetDisplayColor();
|
|
1152
|
+
}
|
|
1069
1153
|
/**
|
|
1070
1154
|
* Check if has selection
|
|
1071
1155
|
*/
|
|
1072
|
-
|
|
1156
|
+
HasSelection() {
|
|
1073
1157
|
return this.SelectedNodes.length > 0 || this._pendingDisplayText != null;
|
|
1074
1158
|
}
|
|
1159
|
+
/** @deprecated Use {@link HasSelection}. */
|
|
1160
|
+
hasSelection() {
|
|
1161
|
+
return this.HasSelection();
|
|
1162
|
+
}
|
|
1075
1163
|
/**
|
|
1076
1164
|
* Get dropdown panel styles
|
|
1077
1165
|
*/
|
|
1078
|
-
|
|
1166
|
+
GetDropdownStyles() {
|
|
1079
1167
|
if (!this.Position) {
|
|
1080
1168
|
return {};
|
|
1081
1169
|
}
|
|
@@ -1086,23 +1174,31 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
1086
1174
|
maxHeight: `${this.Position.maxHeight}px`
|
|
1087
1175
|
};
|
|
1088
1176
|
}
|
|
1177
|
+
/** @deprecated Use {@link GetDropdownStyles}. */
|
|
1178
|
+
getDropdownStyles() {
|
|
1179
|
+
return this.GetDropdownStyles();
|
|
1180
|
+
}
|
|
1089
1181
|
/**
|
|
1090
1182
|
* Get trigger classes
|
|
1091
1183
|
*/
|
|
1092
|
-
|
|
1184
|
+
GetTriggerClasses() {
|
|
1093
1185
|
return {
|
|
1094
1186
|
'tree-dropdown-trigger': true,
|
|
1095
1187
|
'tree-dropdown-trigger--open': this.IsOpen,
|
|
1096
1188
|
'tree-dropdown-trigger--disabled': this.Disabled,
|
|
1097
|
-
'tree-dropdown-trigger--has-value': this.
|
|
1189
|
+
'tree-dropdown-trigger--has-value': this.HasSelection(),
|
|
1098
1190
|
'tree-dropdown-trigger--loading': this.IsLoading && this.ShowLoadingInTrigger
|
|
1099
1191
|
};
|
|
1100
1192
|
}
|
|
1193
|
+
/** @deprecated Use {@link GetTriggerClasses}. */
|
|
1194
|
+
getTriggerClasses() {
|
|
1195
|
+
return this.GetTriggerClasses();
|
|
1196
|
+
}
|
|
1101
1197
|
/**
|
|
1102
1198
|
* Get selected IDs as a string array for passing to tree component.
|
|
1103
1199
|
* Extracts the first key value from each CompositeKey (typically the ID field).
|
|
1104
1200
|
*/
|
|
1105
|
-
|
|
1201
|
+
GetSelectedIDsArray() {
|
|
1106
1202
|
if (!this._value) {
|
|
1107
1203
|
return [];
|
|
1108
1204
|
}
|
|
@@ -1113,15 +1209,19 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
1113
1209
|
return firstValue != null ? String(firstValue) : '';
|
|
1114
1210
|
}).filter(id => id !== '');
|
|
1115
1211
|
}
|
|
1212
|
+
/** @deprecated Use {@link GetSelectedIDsArray}. */
|
|
1213
|
+
getSelectedIDsArray() {
|
|
1214
|
+
return this.GetSelectedIDsArray();
|
|
1215
|
+
}
|
|
1116
1216
|
static ɵfac = function TreeDropdownComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TreeDropdownComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.Renderer2)); };
|
|
1117
1217
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TreeDropdownComponent, selectors: [["mj-tree-dropdown"]], viewQuery: function TreeDropdownComponent_Query(rf, ctx) { if (rf & 1) {
|
|
1118
1218
|
i0.ɵɵviewQuery(_c0, 5)(_c1, 5)(_c2, 5)(_c3, 5);
|
|
1119
1219
|
} if (rf & 2) {
|
|
1120
1220
|
let _t;
|
|
1121
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.
|
|
1122
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.
|
|
1123
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.
|
|
1124
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.
|
|
1221
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.TriggerElement = _t.first);
|
|
1222
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.SearchInput = _t.first);
|
|
1223
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.DropdownPanel = _t.first);
|
|
1224
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.TreeComponent = _t.first);
|
|
1125
1225
|
} }, inputs: { BranchConfig: "BranchConfig", LeafConfig: "LeafConfig", SelectionMode: "SelectionMode", SelectableTypes: "SelectableTypes", DefaultExpansion: "DefaultExpansion", Value: "Value", Placeholder: "Placeholder", EnableSearch: "EnableSearch", SearchConfig: "SearchConfig", DropdownConfig: "DropdownConfig", StyleConfig: "StyleConfig", Clearable: "Clearable", Disabled: "Disabled", ShowIconInDisplay: "ShowIconInDisplay", AutoLoad: "AutoLoad", ShowLoadingInTrigger: "ShowLoadingInTrigger" }, outputs: { ValueChange: "ValueChange", SelectionChange: "SelectionChange", BeforeNodeSelect: "BeforeNodeSelect", AfterNodeSelect: "AfterNodeSelect", BeforeSearch: "BeforeSearch", AfterSearch: "AfterSearch", BeforeDropdownOpen: "BeforeDropdownOpen", AfterDropdownOpen: "AfterDropdownOpen", BeforeDropdownClose: "BeforeDropdownClose", AfterDropdownClose: "AfterDropdownClose", BeforeDataLoad: "BeforeDataLoad", AfterDataLoad: "AfterDataLoad" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 13, vars: 16, consts: [["triggerElement", ""], ["dropdownPanel", ""], ["treeComponent", ""], ["searchInput", ""], [1, "tree-dropdown"], ["tabindex", "0", "role", "combobox", 3, "click", "keydown", "ngClass"], [1, "tree-dropdown-trigger__content"], [1, "tree-dropdown-trigger__icon", 3, "color"], [1, "tree-dropdown-trigger__text"], [1, "tree-dropdown-trigger__loading"], [1, "tree-dropdown-trigger__actions"], ["type", "button", "title", "Clear selection", "tabindex", "-1", 1, "tree-dropdown-trigger__clear"], [1, "tree-dropdown-trigger__chevron"], [1, "fa-solid", 3, "ngClass"], ["role", "tree", 1, "tree-dropdown-panel", 3, "tree-dropdown-panel--open", "tree-dropdown-panel--above", "tree-dropdown-panel--below", "class", "ngStyle"], [1, "tree-dropdown-trigger__icon"], [1, "fa-solid", "fa-spinner", "fa-spin"], ["type", "button", "title", "Clear selection", "tabindex", "-1", 1, "tree-dropdown-trigger__clear", 3, "click"], [1, "fa-solid", "fa-times"], ["role", "tree", 1, "tree-dropdown-panel", 3, "ngStyle"], [1, "tree-dropdown-search"], [1, "tree-dropdown-tree"], [3, "SelectionChange", "BeforeNodeSelect", "AfterNodeSelect", "BeforeDataLoad", "AfterDataLoad", "BranchConfig", "LeafConfig", "SelectionMode", "SelectableTypes", "DefaultExpansion", "SelectedIDs", "AutoLoad", "ShowIcons", "ShowExpandCollapseAll", "AnimateExpandCollapse", "EmptyMessage", "EmptyIcon"], [1, "tree-dropdown-search__input-wrapper"], [1, "fa-solid", "fa-search", "tree-dropdown-search__icon"], ["type", "text", "autocomplete", "off", "spellcheck", "false", 1, "tree-dropdown-search__input", 3, "input", "keydown", "placeholder", "value"], ["type", "button", "tabindex", "-1", 1, "tree-dropdown-search__clear"], ["type", "button", "tabindex", "-1", 1, "tree-dropdown-search__clear", 3, "click"]], template: function TreeDropdownComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1126
1226
|
i0.ɵɵelementStart(0, "div", 4)(1, "div", 5, 0);
|
|
1127
1227
|
i0.ɵɵlistener("click", function TreeDropdownComponent_Template_div_click_1_listener() { return ctx.onTriggerClick(); })("keydown", function TreeDropdownComponent_Template_div_keydown_1_listener($event) { return ctx.onTriggerKeyDown($event); });
|
|
@@ -1220,16 +1320,16 @@ export class TreeDropdownComponent extends BaseAngularComponent {
|
|
|
1220
1320
|
type: Output
|
|
1221
1321
|
}], AfterDataLoad: [{
|
|
1222
1322
|
type: Output
|
|
1223
|
-
}],
|
|
1323
|
+
}], TriggerElement: [{
|
|
1224
1324
|
type: ViewChild,
|
|
1225
1325
|
args: ['triggerElement']
|
|
1226
|
-
}],
|
|
1326
|
+
}], SearchInput: [{
|
|
1227
1327
|
type: ViewChild,
|
|
1228
1328
|
args: ['searchInput']
|
|
1229
|
-
}],
|
|
1329
|
+
}], DropdownPanel: [{
|
|
1230
1330
|
type: ViewChild,
|
|
1231
1331
|
args: ['dropdownPanel']
|
|
1232
|
-
}],
|
|
1332
|
+
}], TreeComponent: [{
|
|
1233
1333
|
type: ViewChild,
|
|
1234
1334
|
args: ['treeComponent']
|
|
1235
1335
|
}] }); })();
|