@naniteninja/dashboard-components-lib 2.1.11 → 2.1.12
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.
|
@@ -5158,6 +5158,7 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5158
5158
|
this.showGlobalMenu = false;
|
|
5159
5159
|
this.activeContextMenuNode = null;
|
|
5160
5160
|
this.contextMenuPosition = { x: 0, y: 0 };
|
|
5161
|
+
this.globalMenuClickListener = null;
|
|
5161
5162
|
this.settingsTriggerPortalViewRef = null;
|
|
5162
5163
|
this.settingsTriggerPortalEl = null;
|
|
5163
5164
|
this.settingsTriggerPortaled = false;
|
|
@@ -5170,6 +5171,8 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5170
5171
|
this.settingsTriggerRafId = null;
|
|
5171
5172
|
this.contextMenuViewRef = null;
|
|
5172
5173
|
this.contextMenuClickListener = null;
|
|
5174
|
+
this.confirmDialogViewRef = null;
|
|
5175
|
+
this.confirmDialogKeyListener = null;
|
|
5173
5176
|
this.pendingGroupingMode = null;
|
|
5174
5177
|
this.alertViewRef = null;
|
|
5175
5178
|
this.alertDismissTimer = null;
|
|
@@ -5191,6 +5194,8 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5191
5194
|
this.dragMoveSubject = new Subject();
|
|
5192
5195
|
this.destroy$ = new Subject();
|
|
5193
5196
|
this.recentlyDroppedId = null;
|
|
5197
|
+
this.runtimeIdSeq = 0;
|
|
5198
|
+
this.runtimeIdByObject = new WeakMap();
|
|
5194
5199
|
// ── Auto-sort ─────────────────────────────────────────────────────────────
|
|
5195
5200
|
this.colorChangeSubject = new Subject();
|
|
5196
5201
|
this.COLOR_CHANGE_DEBOUNCE_MS = 800;
|
|
@@ -5391,6 +5396,7 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5391
5396
|
}
|
|
5392
5397
|
ngOnDestroy() {
|
|
5393
5398
|
this.closeMenus();
|
|
5399
|
+
this.dismissConfirmDialog();
|
|
5394
5400
|
this.dismissAlert();
|
|
5395
5401
|
this.stopEdgeScroll();
|
|
5396
5402
|
this.destroy$.next();
|
|
@@ -5431,8 +5437,21 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5431
5437
|
if (event)
|
|
5432
5438
|
event.stopPropagation();
|
|
5433
5439
|
this.ngZone.run(() => {
|
|
5440
|
+
this.pendingGroupingMode = null;
|
|
5441
|
+
this.dismissConfirmDialog();
|
|
5434
5442
|
this.showGlobalMenu = !this.showGlobalMenu;
|
|
5435
5443
|
this.activeContextMenuNode = null;
|
|
5444
|
+
if (this.showGlobalMenu) {
|
|
5445
|
+
if (!this.globalMenuClickListener) {
|
|
5446
|
+
this.globalMenuClickListener = this.renderer.listen('document', 'click', () => this.closeMenus());
|
|
5447
|
+
}
|
|
5448
|
+
}
|
|
5449
|
+
else {
|
|
5450
|
+
if (this.globalMenuClickListener) {
|
|
5451
|
+
this.globalMenuClickListener();
|
|
5452
|
+
this.globalMenuClickListener = null;
|
|
5453
|
+
}
|
|
5454
|
+
}
|
|
5436
5455
|
this.cdr.markForCheck();
|
|
5437
5456
|
});
|
|
5438
5457
|
}
|
|
@@ -5449,12 +5468,8 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5449
5468
|
const hasManualGroups = this.tabNodes.some(n => n.type === 'group');
|
|
5450
5469
|
if (hasManualGroups && mode !== 'none') {
|
|
5451
5470
|
this.pendingGroupingMode = mode;
|
|
5452
|
-
this.
|
|
5453
|
-
|
|
5454
|
-
if (this.confirmPopper) {
|
|
5455
|
-
this.confirmPopper.show();
|
|
5456
|
-
}
|
|
5457
|
-
}, 100);
|
|
5471
|
+
this.dismissConfirmDialog();
|
|
5472
|
+
this.openConfirmDialog();
|
|
5458
5473
|
return;
|
|
5459
5474
|
}
|
|
5460
5475
|
this.executeGroupBy(mode);
|
|
@@ -5502,22 +5517,41 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5502
5517
|
}
|
|
5503
5518
|
}
|
|
5504
5519
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
5505
|
-
// CONFIRMATION DIALOG (
|
|
5520
|
+
// CONFIRMATION DIALOG (PORTAL)
|
|
5506
5521
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
5522
|
+
openConfirmDialog() {
|
|
5523
|
+
if (this.confirmDialogViewRef)
|
|
5524
|
+
return;
|
|
5525
|
+
this.confirmDialogViewRef = this.viewContainerRef.createEmbeddedView(this.confirmDialogTemplate);
|
|
5526
|
+
this.confirmDialogViewRef.detectChanges();
|
|
5527
|
+
this.confirmDialogViewRef.rootNodes.forEach(n => document.body.appendChild(n));
|
|
5528
|
+
this.confirmDialogKeyListener = this.renderer.listen('document', 'keydown', (event) => {
|
|
5529
|
+
if (event.key !== 'Escape')
|
|
5530
|
+
return;
|
|
5531
|
+
this.ngZone.run(() => this.cancelGroupBy());
|
|
5532
|
+
});
|
|
5533
|
+
}
|
|
5534
|
+
dismissConfirmDialog() {
|
|
5535
|
+
if (this.confirmDialogKeyListener) {
|
|
5536
|
+
this.confirmDialogKeyListener();
|
|
5537
|
+
this.confirmDialogKeyListener = null;
|
|
5538
|
+
}
|
|
5539
|
+
if (this.confirmDialogViewRef) {
|
|
5540
|
+
this.confirmDialogViewRef.rootNodes.forEach(n => this.renderer.removeChild(document.body, n));
|
|
5541
|
+
this.confirmDialogViewRef.destroy();
|
|
5542
|
+
this.confirmDialogViewRef = null;
|
|
5543
|
+
}
|
|
5544
|
+
}
|
|
5507
5545
|
confirmGroupBy() {
|
|
5508
5546
|
if (this.pendingGroupingMode) {
|
|
5509
5547
|
this.executeGroupBy(this.pendingGroupingMode);
|
|
5510
5548
|
this.pendingGroupingMode = null;
|
|
5511
5549
|
}
|
|
5512
|
-
|
|
5513
|
-
this.confirmPopper.hide();
|
|
5514
|
-
}
|
|
5550
|
+
this.dismissConfirmDialog();
|
|
5515
5551
|
}
|
|
5516
5552
|
cancelGroupBy() {
|
|
5517
5553
|
this.pendingGroupingMode = null;
|
|
5518
|
-
|
|
5519
|
-
this.confirmPopper.hide();
|
|
5520
|
-
}
|
|
5554
|
+
this.dismissConfirmDialog();
|
|
5521
5555
|
}
|
|
5522
5556
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
5523
5557
|
// ALERT (TOASTR)
|
|
@@ -5548,6 +5582,12 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5548
5582
|
// GROUP BY
|
|
5549
5583
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
5550
5584
|
executeGroupBy(mode) {
|
|
5585
|
+
this.pendingGroupingMode = null;
|
|
5586
|
+
this.dismissConfirmDialog();
|
|
5587
|
+
if (this.globalMenuClickListener) {
|
|
5588
|
+
this.globalMenuClickListener();
|
|
5589
|
+
this.globalMenuClickListener = null;
|
|
5590
|
+
}
|
|
5551
5591
|
this.currentGroupingMode = mode;
|
|
5552
5592
|
if (mode === 'none') {
|
|
5553
5593
|
// Flatten all groups → individual ungrouped nodes
|
|
@@ -5557,7 +5597,7 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5557
5597
|
flat.push(node);
|
|
5558
5598
|
}
|
|
5559
5599
|
else {
|
|
5560
|
-
node.data.items.forEach((item) => flat.push({ id: `ungrouped-${this.
|
|
5600
|
+
node.data.items.forEach((item) => flat.push({ id: `ungrouped-${this.getRuntimeId(item)}`, type: 'item', data: item }));
|
|
5561
5601
|
}
|
|
5562
5602
|
});
|
|
5563
5603
|
this.tabNodes = flat;
|
|
@@ -5584,7 +5624,7 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5584
5624
|
groups[safeId].data.items.push(item);
|
|
5585
5625
|
}
|
|
5586
5626
|
else {
|
|
5587
|
-
unassigned.push({ id:
|
|
5627
|
+
unassigned.push({ id: `item-${this.getRuntimeId(item)}`, type: 'item', data: item });
|
|
5588
5628
|
}
|
|
5589
5629
|
});
|
|
5590
5630
|
// Sort items within each group by response time
|
|
@@ -5645,12 +5685,14 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5645
5685
|
*/
|
|
5646
5686
|
mergeNewItemsAfterRestore(storedRule) {
|
|
5647
5687
|
const restoredIds = this.collectCurrentIds();
|
|
5648
|
-
const newItems = this.items.filter(i =>
|
|
5688
|
+
const newItems = this.items.filter(i => {
|
|
5689
|
+
const id = this.getSafeId(i);
|
|
5690
|
+
return id ? !restoredIds.has(id) : true;
|
|
5691
|
+
});
|
|
5649
5692
|
if (!newItems.length) {
|
|
5650
5693
|
this.refreshDataReferences();
|
|
5651
5694
|
return;
|
|
5652
5695
|
}
|
|
5653
|
-
const now = Date.now();
|
|
5654
5696
|
if (storedRule === 'response') {
|
|
5655
5697
|
this.executeGroupBy('response');
|
|
5656
5698
|
}
|
|
@@ -5659,18 +5701,21 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5659
5701
|
}
|
|
5660
5702
|
else {
|
|
5661
5703
|
// Manual/None → leftmost ungrouped
|
|
5662
|
-
[...newItems].reverse().forEach(item => this.tabNodes.unshift({ id: `new-${this.
|
|
5704
|
+
[...newItems].reverse().forEach(item => this.tabNodes.unshift({ id: `new-${this.getRuntimeId(item)}`, type: 'item', data: item }));
|
|
5663
5705
|
}
|
|
5664
5706
|
this.refreshDataReferences();
|
|
5665
5707
|
}
|
|
5666
5708
|
mergeAsUngroupedLeft() {
|
|
5667
5709
|
const currentIds = this.collectCurrentIds();
|
|
5668
|
-
const newItems = this.items.filter(i =>
|
|
5710
|
+
const newItems = this.items.filter(i => {
|
|
5711
|
+
const id = this.getSafeId(i);
|
|
5712
|
+
return id ? !currentIds.has(id) : true;
|
|
5713
|
+
});
|
|
5669
5714
|
if (!newItems.length) {
|
|
5670
5715
|
this.refreshDataReferences();
|
|
5671
5716
|
return;
|
|
5672
5717
|
}
|
|
5673
|
-
[...newItems].reverse().forEach(item => this.tabNodes.unshift({ id: `new-${this.
|
|
5718
|
+
[...newItems].reverse().forEach(item => this.tabNodes.unshift({ id: `new-${this.getRuntimeId(item)}`, type: 'item', data: item }));
|
|
5674
5719
|
this.refreshDataReferences();
|
|
5675
5720
|
}
|
|
5676
5721
|
mergePerResponseRule() { this.executeGroupBy('response'); }
|
|
@@ -5678,8 +5723,10 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5678
5723
|
collectCurrentIds() {
|
|
5679
5724
|
const ids = new Set();
|
|
5680
5725
|
this.tabNodes.forEach(n => n.type === 'group'
|
|
5681
|
-
? n.data.items.forEach((i) =>
|
|
5682
|
-
|
|
5726
|
+
? n.data.items.forEach((i) => { const id = this.getSafeId(i); if (id)
|
|
5727
|
+
ids.add(id); })
|
|
5728
|
+
: (() => { const id = this.getSafeId(n.data); if (id)
|
|
5729
|
+
ids.add(id); })());
|
|
5683
5730
|
return ids;
|
|
5684
5731
|
}
|
|
5685
5732
|
getStoredRule() {
|
|
@@ -5727,6 +5774,10 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
5727
5774
|
closeMenus() {
|
|
5728
5775
|
this.showGlobalMenu = false;
|
|
5729
5776
|
this.activeContextMenuNode = null;
|
|
5777
|
+
if (this.globalMenuClickListener) {
|
|
5778
|
+
this.globalMenuClickListener();
|
|
5779
|
+
this.globalMenuClickListener = null;
|
|
5780
|
+
}
|
|
5730
5781
|
if (this.contextMenuViewRef) {
|
|
5731
5782
|
this.contextMenuViewRef.rootNodes.forEach(n => this.renderer.removeChild(document.body, n));
|
|
5732
5783
|
this.contextMenuViewRef.destroy();
|
|
@@ -6214,17 +6265,21 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
6214
6265
|
}
|
|
6215
6266
|
updateDisplayItems() {
|
|
6216
6267
|
const prevActive = this.displayItems?.length > 0 ? this.displayItems[this.activeIndex] : null;
|
|
6217
|
-
const itemMap = new Map(this.items.map(i => [this.getSafeId(i), i]));
|
|
6268
|
+
const itemMap = new Map(this.items.map(i => [this.getSafeId(i), i]).filter(([id]) => !!id));
|
|
6218
6269
|
this.displayItems = [];
|
|
6219
6270
|
this.tabNodes.forEach(node => {
|
|
6220
6271
|
if (node.type === 'item') {
|
|
6221
|
-
const
|
|
6272
|
+
const id = this.getSafeId(node.data);
|
|
6273
|
+
const fresh = id ? itemMap.get(id) : undefined;
|
|
6222
6274
|
if (fresh)
|
|
6223
6275
|
node.data = fresh;
|
|
6224
6276
|
this.displayItems.push(node.data);
|
|
6225
6277
|
}
|
|
6226
6278
|
else {
|
|
6227
|
-
node.data.items = node.data.items.map((item) =>
|
|
6279
|
+
node.data.items = node.data.items.map((item) => {
|
|
6280
|
+
const itemId = this.getSafeId(item);
|
|
6281
|
+
return itemId ? itemMap.get(itemId) ?? item : item;
|
|
6282
|
+
});
|
|
6228
6283
|
this.displayItems.push(...node.data.items);
|
|
6229
6284
|
}
|
|
6230
6285
|
});
|
|
@@ -6674,11 +6729,22 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
6674
6729
|
trackByItem(index, item) {
|
|
6675
6730
|
if (!item)
|
|
6676
6731
|
return `index-${index}`;
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
const
|
|
6681
|
-
|
|
6732
|
+
return `rid-${this.getRuntimeId(item)}`;
|
|
6733
|
+
}
|
|
6734
|
+
getRuntimeId(item) {
|
|
6735
|
+
const safe = this.getSafeId(item);
|
|
6736
|
+
if (safe)
|
|
6737
|
+
return safe;
|
|
6738
|
+
if (item && typeof item === 'object') {
|
|
6739
|
+
const obj = item;
|
|
6740
|
+
const existing = this.runtimeIdByObject.get(obj);
|
|
6741
|
+
if (existing)
|
|
6742
|
+
return existing;
|
|
6743
|
+
const next = `anon-${++this.runtimeIdSeq}`;
|
|
6744
|
+
this.runtimeIdByObject.set(obj, next);
|
|
6745
|
+
return next;
|
|
6746
|
+
}
|
|
6747
|
+
return `anon-${++this.runtimeIdSeq}`;
|
|
6682
6748
|
}
|
|
6683
6749
|
getSafeId(item) {
|
|
6684
6750
|
if (!item)
|
|
@@ -6794,11 +6860,11 @@ class LibDashboardSwipeableTabsComponent {
|
|
|
6794
6860
|
requestAnimationFrame(() => { ref.mainSwiperInstance?.update(); ref.thumbsSwiperInstance?.update(); });
|
|
6795
6861
|
}
|
|
6796
6862
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LibDashboardSwipeableTabsComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6797
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LibDashboardSwipeableTabsComponent, isStandalone: true, selector: "lib-dashboard-swipeable-tabs", inputs: { thumbsSwiperOptions: "thumbsSwiperOptions", mainSwiperOptions: "mainSwiperOptions", activeIndex: "activeIndex", bottomThumbs: "bottomThumbs", slideContentMaxHeight: "slideContentMaxHeight", mainSwiperHeight: "mainSwiperHeight", subMainSwiperHeight: "subMainSwiperHeight", thumbsSwiperHeight: "thumbsSwiperHeight", generalSwiperHeight: "generalSwiperHeight", enableGrouping: "enableGrouping", enableDragAndDrop: "enableDragAndDrop", enableTabBarScrollDrag: "enableTabBarScrollDrag", items: "items", thumbTemplate: "thumbTemplate", contentTemplate: "contentTemplate", groupingAdapter: "groupingAdapter", showPrefRejectButton: "showPrefRejectButton", menuPosition: "menuPosition" }, outputs: { repositionModeChange: "repositionModeChange", activeIndexChange: "activeIndexChange", itemClicked: "itemClicked", expandedIdChange: "expandedIdChange" }, queries: [{ propertyName: "thumbSlides", first: true, predicate: ["thumbSlides"], descendants: true }], viewQueries: [{ propertyName: "thumbSwiper", first: true, predicate: ["thumbSwiper"], descendants: true }, { propertyName: "mainSwiper", first: true, predicate: ["mainSwiper"], descendants: true }, { propertyName: "settingsTriggerWrapperEl", first: true, predicate: ["settingsTriggerWrapperEl"], descendants: true }, { propertyName: "settingsTriggerPortalTemplate", first: true, predicate: ["settingsTriggerPortalTemplate"], descendants: true }, { propertyName: "contextMenuTemplate", first: true, predicate: ["contextMenuTemplate"], descendants: true }, { propertyName: "confirmPopper", first: true, predicate: ["confirmPopper"], descendants: true }, { propertyName: "alertTemplate", first: true, predicate: ["alertTemplate"], descendants: true }, { propertyName: "tabBarContainer", first: true, predicate: ["tabBarContainer"], descendants: true }, { propertyName: "expandedPortalTemplate", first: true, predicate: ["expandedPortalTemplate"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"swipeable-tabs-container\"\n [class.bottom-thumbs]=\"bottomThumbs\"\n [ngStyle]=\"{ height: generalSwiperHeight }\"\n [style.--thumbs-height]=\"thumbsSwiperHeight\"\n>\n\n <!-- \u2500\u2500 LEGACY MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (!enableGrouping) {\n <ng-container>\n <swiper-container #thumbSwiper init=\"false\" class=\"thumb-swiper container-sides-shadow\" [ngStyle]=\"{ height: thumbsSwiperHeight }\">\n <ng-content select=\"[thumb-slides]\"></ng-content>\n </swiper-container>\n <div class=\"swiper-container main-swiper\" [style.max-height]=\"slideContentMaxHeight\" [ngStyle]=\"{ height: mainSwiperHeight }\">\n <swiper-container #mainSwiper init=\"false\" class=\"main-swiper\" [class.container-sides-shadow]=\"activeIndex !== 0\" [ngStyle]=\"{ height: subMainSwiperHeight }\">\n <ng-content select=\"[main-slides]\"></ng-content>\n </swiper-container>\n </div>\n </ng-container>\n }\n\n <!-- \u2500\u2500 GROUPING MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (enableGrouping) {\n <ng-container>\n\n <!-- Settings trigger -->\n <div class=\"settings-trigger-wrapper\" #settingsTriggerWrapperEl>\n <div class=\"settings-trigger\" [class.settings-trigger--hidden]=\"settingsTriggerPortaled\" (click)=\"toggleGlobalMenu($event)\" [libPopper]=\"confirmPopper\" [popperTrigger]=\"'none'\">\n <i class=\"pi pi-cog\"></i>\n </div>\n @if (showGlobalMenu) {\n <div class=\"global-menu\" [ngClass]=\"'menu-' + menuPosition\" (click)=\"$event.stopPropagation()\">\n <div class=\"menu-item\" (click)=\"requestGroupBy('response')\">Group by Response</div>\n <div class=\"menu-item\" (click)=\"requestGroupBy('client')\">Group by Client</div>\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"restoreCustomGroups()\">Restore Custom Groups</div>\n <div class=\"menu-item\" (click)=\"storeCustomGroups()\">Store Custom Groups</div>\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"ungroupAll()\">Ungroup All</div>\n </div>\n }\n </div>\n\n <ng-template #settingsTriggerPortalTemplate>\n <div\n class=\"settings-trigger-wrapper settings-trigger-wrapper-portal\"\n [style.left.px]=\"settingsTriggerPortalLeft\"\n [style.top.px]=\"settingsTriggerPortalTop\"\n >\n <div class=\"settings-trigger\" (click)=\"toggleGlobalMenu($event)\" [libPopper]=\"confirmPopper\" [popperTrigger]=\"'none'\">\n <i class=\"pi pi-cog\"></i>\n </div>\n </div>\n </ng-template>\n\n <!-- Tab Bar -->\n <div class=\"tab-bar-container\"\n #tabBarContainer\n cdkScrollable\n [class.dragging-active]=\"isDragging\"\n [class.grouping-animating]=\"groupingAnimating\"\n [class.grab-cursor]=\"!repositionMode && !isScrollDragging\"\n [class.grabbing-cursor]=\"isScrollDragging\"\n [ngStyle]=\"{ minHeight: thumbsSwiperHeight }\"\n tabindex=\"0\">\n\n <div\n cdkDropList\n [id]=\"rootDropListId\"\n [cdkDropListConnectedTo]=\"connectedDropLists\"\n [cdkDropListEnterPredicate]=\"canDropToRoot\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"tabNodes\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"tab-list-root\">\n\n @for (node of tabNodes; track trackByNode($index, node); let i = $index) {\n <div cdkDrag\n [cdkDragData]=\"node\"\n [cdkDragDisabled]=\"!enableDragAndDrop || isRootNodeDragDisabled(node)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"dragEnded($event)\"\n class=\"tab-node-wrapper\"\n [class.potential-group-target]=\"isItem(node) && potentialGroupTargetId === getSafeId(node.data)\"\n [attr.data-id]=\"isItem(node) ? getSafeId(node.data) : null\"\n (mousedown)=\"onNodeDown($event)\"\n (touchstart)=\"onNodeDown($event)\"\n (mouseup)=\"onNodeMouseUp()\"\n (touchend)=\"onNodeMouseUp()\">\n\n <div *cdkDragPreview>\n <ng-container *ngTemplateOutlet=\"nodePreviewTemplate; context: { node: node }\"></ng-container>\n </div>\n <div *cdkDragPlaceholder [class.reposition-placeholder]=\"repositionMode\"></div>\n\n <!-- \u2500\u2500 Case 1: Ungrouped Item \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (isItem(node)) {\n <ng-container>\n <div class=\"tab-item ungrouped\"\n [class.is-expanded-source]=\"expandedItemId === getSafeId(node.data)\"\n [attr.data-expanded-id]=\"expandedItemId === getSafeId(node.data) ? expandedItemId : null\"\n [class.active]=\"displayItems.indexOf(node.data) === activeIndex\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(node.data)\"\n (click)=\"onItemClick($event, node)\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: false, expanded: false }\"></ng-container>\n </div>\n\n @if (potentialGroupTargetId === getSafeId(node.data)) {\n <div class=\"visual-group-wrapper\">\n <div class=\"group-header-vertical\"></div>\n <div class=\"group-list-visual\">\n <div class=\"tab-item\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: true, expanded: false }\"></ng-container>\n </div>\n <div class=\"tab-item ghost-item\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: draggedItemData?.data, grouped: true, expanded: false }\"></ng-container>\n </div>\n </div>\n </div>\n }\n </ng-container>\n }\n\n <!-- \u2500\u2500 Case 2: Group Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (isGroup(node)) {\n <ng-container>\n <div class=\"group-container\"\n [class.collapsed]=\"node.data.collapsed\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(node.data)\"\n [class.pulsating-group]=\"repositionMode && repositionTargetId === getSafeId(node.data)\"\n [style.border-color]=\"node.data.color\"\n [style.--group-accent-color]=\"node.data.color\"\n cdkDragHandle\n [cdkDragHandleDisabled]=\"!enableDragAndDrop || isRootNodeDragDisabled(node) || repositionTargetGroupId === node.id\"\n (mousedown)=\"onNodeDown($event)\"\n (touchstart)=\"onNodeDown($event)\"\n (mouseup)=\"onNodeMouseUp()\"\n (touchend)=\"onNodeMouseUp()\">\n\n <div class=\"group-header-vertical\" (click)=\"toggleGroup(node.data)\">\n <div class=\"group-title-vertical\">\n <span class=\"group-title-text\">{{ getTruncatedTitle(node.data.title, node.data.collapsed) }}</span>\n </div>\n <div class=\"group-ellipsis-vertical\"\n (click)=\"openContextMenu($event, node); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n (touchstart)=\"$event.stopPropagation()\">\n <div class=\"group-ellipsis-dot\"></div>\n <div class=\"group-ellipsis-dot\"></div>\n <div class=\"group-ellipsis-dot\"></div>\n </div>\n </div>\n\n <div cdkDropList\n [id]=\"'group-list-' + getSafeId(node.data)\"\n [cdkDropListConnectedTo]=\"connectedDropLists\"\n [cdkDropListData]=\"node.data.items\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListEnterPredicate]=\"canDropToGroup\"\n cdkDropListOrientation=\"horizontal\"\n class=\"group-list\"\n [class.collapsed-drop-target]=\"node.data.collapsed && isDragging\">\n\n @for (item of node.data.items; track trackByItem($index, item)) {\n <div class=\"tab-item\"\n cdkDrag\n [class.is-expanded-source]=\"expandedItemId === getSafeId(item)\"\n [attr.data-expanded-id]=\"expandedItemId === getSafeId(item) ? expandedItemId : null\"\n [cdkDragData]=\"{ type: 'item', data: item }\"\n [cdkDragDisabled]=\"!enableDragAndDrop || isItemDragDisabled(getSafeId(item), node.id)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"dragEnded($event)\"\n [class.active]=\"displayItems.indexOf(item) === activeIndex\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(item)\"\n (click)=\"onItemClick($event, { type: 'item', data: item, id: getSafeId(item) })\">\n\n <div *cdkDragPreview>\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item, grouped: true, expanded: false }\"></ng-container>\n </div>\n <div *cdkDragPlaceholder [class.reposition-placeholder]=\"repositionMode\"></div>\n\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item, grouped: true, expanded: false }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </ng-container>\n }\n </div>\n }\n\n <!-- Drag preview template -->\n <ng-template #nodePreviewTemplate let-node=\"node\">\n @if (isItem(node)) {\n <div class=\"tab-item ungrouped\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: false, expanded: false }\"></ng-container>\n </div>\n }\n @if (isGroup(node)) {\n <div class=\"group-container collapsed\"\n [style.border-color]=\"node.data.color\"\n [style.--group-accent-color]=\"node.data.color\">\n <div class=\"group-header-vertical\">\n <div class=\"group-title-vertical\">\n <span class=\"group-title-text\">{{ getTruncatedTitle(node.data.title, true) }}</span>\n </div>\n </div>\n </div>\n }\n </ng-template>\n\n </div>\n </div>\n\n <ng-template #expandedPortalTemplate>\n @if (expandedItemId && portalRect && !(isDragging && getSafeId(draggedItemData?.data) === expandedItemId)) {\n <div class=\"expanded-item-portal\"\n [attr.data-expanded-portal-id]=\"expandedItemId\"\n [style.left.px]=\"portalRect.left\"\n [style.top.px]=\"portalRect.top\"\n [style.width.px]=\"portalRect.width\"\n (pointerdown)=\"onScrollPointerDown($event)\"\n (mousedown)=\"onPortalDown($event)\"\n (touchstart)=\"onPortalDown($event)\"\n (click)=\"onPortalClick($event)\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: expandedItemRef, grouped: false, expanded: true }\"></ng-container>\n </div>\n }\n </ng-template>\n\n @if (showPrefRejectButton) {\n <button type=\"button\" class=\"tabs-pref-reject-button\">\n <span class=\"tabs-pref-reject-button__icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\">\n <g>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M10.9353 4.11938C11.1384 4.3225 11.1384 4.65183 10.9353 4.85495L2.35324 13.437C2.15012 13.6401 1.82079 13.6401 1.61767 13.437C1.41455 13.2339 1.41455 12.9046 1.61767 12.7014L10.1997 4.11938C10.4028 3.91626 10.7322 3.91626 10.9353 4.11938Z\" fill=\"#FE3C72\"/>\n <circle cx=\"6.14645\" cy=\"8.64816\" r=\"4.0\" stroke=\"#FE3C72\" stroke-width=\"1\"/>\n </g>\n </svg>\n </span>\n <span class=\"tabs-pref-reject-button__label\">Reject</span>\n </button>\n }\n\n <!-- Global menu overlay -->\n @if (showGlobalMenu) {\n <div class=\"global-menu-overlay\" (click)=\"toggleGlobalMenu($event)\"></div>\n }\n\n <!-- Context menu overlay -->\n @if (activeContextMenuNode) {\n <div class=\"context-menu-overlay\" (click)=\"closeMenus()\"></div>\n }\n\n <!-- \u2500\u2500 Context menu (portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #contextMenuTemplate>\n @if (activeContextMenuNode) {\n <div class=\"context-menu\"\n [style.left.px]=\"contextMenuPosition.x\"\n [style.top.px]=\"contextMenuPosition.y\"\n style=\"position: fixed; z-index: 100000;\">\n @if (activeContextMenuNode?.type === 'group' || activeContextMenuNode?.type === 'item') {\n <div class=\"menu-item\" (click)=\"toggleRepositionMode()\">\n {{ repositionMode && (!repositionTargetId || repositionTargetId === getSafeId(activeContextMenuNode?.data)) ? 'End Reposition' : 'Reposition' }}\n </div>\n }\n @if (activeContextMenuNode?.type === 'group') {\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"handleMenuAction('ungroup', activeContextMenuNode!)\">Ungroup</div>\n }\n </div>\n }\n </ng-template>\n\n <!-- \u2500\u2500 Confirmation dialog (Popper) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <lib-popper-content #confirmPopper>\n <div class=\"popover-container\">\n <div class=\"m-title f-w-700 f-lg h-160 f-white\">Overwrite Manual Groups?</div>\n <span class=\"message f-w-400 f-md h-150 f-gray\">\n This operation will discard your current manual arrangement.\n Continue?\n </span>\n <div class=\"buttons\">\n <lib-secondary-btn (click)=\"cancelGroupBy()\" type=\"button\">Cancel</lib-secondary-btn>\n <lib-primary-btn (click)=\"confirmGroupBy()\" type=\"button\">Continue</lib-primary-btn>\n </div>\n </div>\n </lib-popper-content>\n\n <!-- \u2500\u2500 Alert / Toastr (portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #alertTemplate>\n <div class=\"tabs-alert-host\">\n <lib-alert-popup\n [title]=\"alertTitle\"\n [description]=\"alertDescription\"\n [timeState]=\"alertTimeState\"\n (closed)=\"dismissAlert()\">\n </lib-alert-popup>\n </div>\n </ng-template>\n\n <!-- Main Content Swiper -->\n <div class=\"swiper-container main-swiper\" [style.max-height]=\"slideContentMaxHeight\" [ngStyle]=\"{ height: mainSwiperHeight }\">\n <swiper-container #mainSwiper init=\"false\" class=\"main-swiper\"\n [class.container-sides-shadow]=\"activeIndex !== 0\"\n [ngStyle]=\"{ height: subMainSwiperHeight }\">\n @for (item of displayItems; track trackByItem($index, item)) {\n <swiper-slide>\n <ng-container *ngTemplateOutlet=\"contentTemplate; context: { $implicit: item, index: $index }\"></ng-container>\n </swiper-slide>\n }\n </swiper-container>\n </div>\n\n </ng-container>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;min-width:0;height:100%;display:flex;flex-direction:column;padding-top:0;font-family:Gilroy,sans-serif}.swipeable-tabs-container{position:relative;display:flex;width:100%;height:100%;min-height:0;flex-direction:column;flex:1}.swipeable-tabs-container.bottom-thumbs{flex-direction:column-reverse}.swipeable-tabs-container>.main-swiper{flex:1;display:flex;flex-direction:column;z-index:100}.swipeable-tabs-container swiper-container{position:relative;display:block;overflow:auto;width:100%;height:100%}.swipeable-tabs-container swiper-container{scrollbar-width:none}.swipeable-tabs-container swiper-container::-webkit-scrollbar{display:none}.expanded-item-portal{position:fixed;transform:translate(-50%,-50%);z-index:1000;pointer-events:auto}.settings-trigger-wrapper{position:absolute;top:-15px;right:0;z-index:3000;pointer-events:none}.settings-trigger-wrapper.settings-trigger-wrapper-portal{position:fixed;top:0;right:auto;z-index:3000;pointer-events:none}.settings-trigger{padding:8px;cursor:pointer;color:#fffc;transition:all .3s ease;pointer-events:auto;display:flex;align-items:center;justify-content:center;background:transparent;background:radial-gradient(circle,rgba(0,0,0,.9) 0%,transparent 70%);box-shadow:none;border:none;border-radius:50%}.settings-trigger:hover{color:#fff;background:radial-gradient(circle,rgba(0,0,0,.95) 0%,transparent 70%)}.settings-trigger i{font-size:1.5rem;filter:drop-shadow(0px 0px 2px rgba(0,0,0,.8))}.settings-trigger.settings-trigger--hidden{visibility:hidden;pointer-events:none}.global-menu-overlay,.context-menu-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2000;background:transparent}.global-menu{position:absolute;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border:none;border-radius:13px;padding:5px 0;min-width:150px;z-index:3001;display:flex;flex-direction:column;overflow:hidden;right:0;left:auto;pointer-events:auto}.popover-container{pointer-events:auto;z-index:5000}.menu-up{top:auto;bottom:100%;margin-bottom:10px;margin-top:0;transform-origin:bottom right;animation:fadeIn .2s ease-out}.menu-down{top:100%;bottom:auto;margin-top:10px;margin-bottom:0;transform-origin:top right;animation:fadeInDown .2s ease-out}.context-menu{position:fixed;margin-left:-17px;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border:none;border-radius:13px;padding:5px 0;min-width:150px;z-index:1002;display:flex;flex-direction:column;overflow:hidden}.context-menu{animation:scaleIn .15s ease-out}.menu-item{padding:12px 20px;color:#ffffffe6;font-family:Gilroy,sans-serif;font-weight:700;font-size:11px;line-height:100%;letter-spacing:.07px;vertical-align:middle;cursor:pointer;transition:background .2s;white-space:nowrap;display:flex;align-items:center}.menu-item:hover{background:#ffffff1a}.global-menu .menu-item{justify-content:flex-end;text-align:right;padding-right:20px}.context-menu .menu-item{justify-content:flex-start;text-align:left;padding-left:20px}.menu-separator{height:1px;background:linear-gradient(to right,transparent,rgba(255,255,255,.3),transparent);margin:8px auto;width:50%}.global-menu .menu-separator{margin-left:auto;margin-right:10%}.context-menu .menu-separator{margin-right:auto;margin-left:10%}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes scaleIn{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}.item-ellipsis{cursor:pointer;color:#ffffff80;padding:2px;border-radius:50%;transition:all .2s}.item-ellipsis:hover{color:#fff;background:#ffffff1a}.item-ellipsis i{font-size:.9rem}.tab-item{width:54px;min-width:27px;height:54px;display:flex;align-items:center;justify-content:center;line-height:0}.tab-item img,.tab-item .avatar{width:auto;height:auto;object-fit:cover;border-radius:50%;margin:0}.tab-item.is-expanded-source{visibility:hidden;min-width:174px!important;flex-shrink:0}.tab-item.expanded-item{height:auto!important;width:auto!important}.tab-item.ungrouped{position:relative}.tab-item.ungrouped .item-ellipsis{position:absolute;bottom:0;right:0;z-index:10;background:#00000080}.tab-bar-container{display:flex;flex-direction:row;overflow-x:auto;overflow-y:hidden;width:100%;max-width:100%;min-width:0;flex-shrink:0;position:relative;z-index:1000;pointer-events:auto;-ms-overflow-style:none;scrollbar-width:none}.tab-bar-container:focus{outline:none}.tab-bar-container.grab-cursor{cursor:grab}.tab-bar-container.grabbing-cursor{cursor:grabbing;-webkit-user-select:none;user-select:none}.tab-bar-container::-webkit-scrollbar{display:none}.tab-bar-container.grouping-animating .cdk-drag-animating{transition:none!important}.tab-bar-container.grouping-animating .tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder){transition:none!important}.tab-bar-container.grouping-animating .cdk-drag-preview{display:none!important}.tabs-pref-reject-button{position:absolute;left:30%;transform:translate(-50%);bottom:calc(var(--thumbs-height, 40px) + 5px);display:inline-flex;align-items:center;gap:6px;padding:0 10px;height:29px;border:none;border-radius:8px;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 2px 4px #00000040,0 4px 4px #00000040,2px -2px 3px #0006 inset,0 -2px 8px #fff3 inset;color:#d9d9d9;font-family:Gilroy,sans-serif;font-size:8px;letter-spacing:.07px;cursor:pointer;z-index:1100}.tabs-pref-reject-button__icon{display:flex;align-items:center;justify-content:center}.tabs-pref-reject-button__label{line-height:1}.tab-list-root{display:flex;flex-direction:row;align-items:center;gap:10px;padding:0 100px 0 20px;min-width:100%;width:max-content;flex-shrink:0;flex-grow:1;height:100%}.tab-list-root .cdk-drag-placeholder{width:2px!important;min-width:2px!important;height:40px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;flex:0 0 auto;visibility:visible!important}.tab-node-wrapper{display:flex;align-items:center;flex-shrink:0;pointer-events:auto;position:relative;z-index:2;width:auto;min-width:min-content}.cdk-drag-preview{box-sizing:border-box;border-radius:0;box-shadow:none;z-index:9999!important;opacity:.5;width:auto;height:auto;display:inline-flex;align-items:center;justify-content:center;overflow:visible;pointer-events:none;scrollbar-width:none}.cdk-drag-preview::-webkit-scrollbar{display:none}.recently-dropped{opacity:.5;animation:fadeBackIn 1s ease-in forwards;animation-delay:2s}@keyframes fadeBackIn{0%{opacity:.5}to{opacity:1}}.cdk-drag-placeholder{opacity:0}.hidden-placeholder~.cdk-drag-preview,.tab-node-wrapper:has(.hidden-placeholder){transition:none!important}.tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.group-container{border:none;position:relative;display:flex;flex-direction:row;align-items:flex-start;padding:0 0 0 4px;box-sizing:border-box;isolation:isolate;margin-right:20px;background:transparent;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 8px 32px #0000005e,inset 0 1px #ffffff4d;border-radius:9px;overflow:visible;transition:all .3s ease}.group-container.pulsating-group{animation:pulsate-group-border 1.5s infinite}.group-container:before{content:\"\";position:absolute;inset:0 auto 0 0;width:min(45px,50%);background:linear-gradient(to right,var(--group-accent-color, rgba(255, 255, 255, .1)),transparent);opacity:.6;filter:blur(15px);z-index:0;pointer-events:none;border-radius:inherit;clip-path:inset(0 0 0 0 round 9px)}.group-container:not(:has(.tab-item.is-expanded-source)){overflow:hidden}.group-container:has(.tab-item.is-expanded-source){overflow:visible;z-index:50}.group-container:has(.tab-item.is-expanded-source):before{clip-path:inset(0 0 0 0 round 9px);overflow:hidden}.group-container.collapsed{width:auto;max-width:none;padding-left:2px}.group-container.collapsed .group-list,.group-container.collapsed .group-ellipsis-vertical{display:none}.group-container.collapsed:before{width:min(32px,30%)}.group-container:has(.tab-item.expanded-item){overflow:visible;z-index:50}@keyframes pulsate-group-border{0%{box-shadow:0 0 #ffffffb3,0 8px 32px #0000005e,inset 0 1px #ffffff4d}70%{box-shadow:0 0 0 6px #fff0,0 8px 32px #0000005e,inset 0 1px #ffffff4d}to{box-shadow:0 0 #fff0,0 8px 32px #0000005e,inset 0 1px #ffffff4d}}.group-title-text{font-family:Calistoga,serif;font-weight:400;font-style:normal;font-size:10px;line-height:100%;letter-spacing:0%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff6;max-height:40px;text-align:center;width:100%;display:block;margin-top:6px}.group-header-vertical{width:30px;align-self:stretch;display:flex;flex-direction:column;padding:0 2px;cursor:grab;z-index:20;position:relative;height:54px;max-height:54px;background:transparent}.group-header-vertical:before{content:\"\";position:absolute;inset:0;background:linear-gradient(to right,var(--group-accent-color, rgba(255, 255, 255, .1)),transparent);opacity:.5;filter:blur(4px);z-index:-1}.group-header-vertical>*{position:relative;z-index:1}.group-container.collapsed{border-radius:13px}.group-container.collapsed .group-header-vertical{justify-content:center;align-items:center;width:18px}.group-container.collapsed .group-title-text{margin-bottom:5px;text-align:center}.group-container:not(.collapsed) .group-header-vertical{justify-content:space-around;align-items:flex-start;padding-left:0;padding-bottom:0;padding-top:0}.group-title-vertical{display:flex;align-items:center;justify-content:center;writing-mode:vertical-rl;transform:rotate(180deg);padding:0;margin-bottom:0;overflow:hidden;min-height:40px}.group-ellipsis-vertical{cursor:pointer;align-items:center;justify-content:space-between;width:100%;height:auto;position:static;margin:-11px 0 0;padding-left:0;display:flex;justify-content:flex-start;gap:3px;padding-bottom:5px}.group-ellipsis-vertical:hover{opacity:.7}.group-ellipsis-vertical .group-ellipsis-dot{width:3px;height:3px;background-color:#fff;border-radius:50%!important;display:block}.tab-bar-container.dragging-active .group-header-vertical{z-index:1;pointer-events:none}.group-list{padding-top:2px;display:flex;align-items:center;justify-content:space-around;min-width:40px;margin-left:-13.5px;margin-right:-11.5px;margin-top:-7.5px;gap:20px;border-radius:4px;position:relative;z-index:1;pointer-events:auto}.group-list .tab-item.is-expanded-source,.group-list .tab-item.is-expanded-source.cdk-drag-placeholder{min-width:174px!important;visibility:visible!important;opacity:.5}.group-list.collapsed-drop-target{position:absolute;top:0;left:0;width:100%;height:100%;min-width:unset;background:#ffffff4d;border:2px dashed rgba(255,255,255,.8);z-index:50;border-radius:16px}.group-list.collapsed-drop-target .tab-item{display:none}.reposition-placeholder{width:2px!important;min-width:2px!important;height:40px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;border:none;box-shadow:none;flex:0 0 auto}.group-list .cdk-drag-placeholder{width:2px!important;min-width:2px!important;height:46px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;border:none;box-shadow:0 0 6px 2px #fe3c7299!important;flex:0 0 auto;visibility:visible!important}.hidden-placeholder{visibility:hidden!important;pointer-events:none!important}.tab-node-wrapper.potential-group-target .tab-item.ungrouped{display:none}.visual-group-wrapper{border:none;display:flex;flex-direction:row;align-items:flex-start;padding:3px 3px 3px 4px;background:transparent;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 8px 32px #0000005e,inset 0 1px #ffffff4d;border-radius:9px;overflow:hidden;border:1px solid rgba(255,255,255,.2)}.visual-group-wrapper .group-header-vertical{width:18px;height:54px;background:#ffffff1a}.visual-group-wrapper .group-list-visual{display:flex;align-items:center;justify-content:space-around;gap:4.5px;margin-left:-4px;padding-top:2px}.visual-group-wrapper .ghost-item{opacity:.3;filter:grayscale(100%)}.grabbing-cursor{cursor:grabbing!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder),.group-list.cdk-drop-list-dragging .tab-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.05)}to{transform:scale(1)}}.tabs-confirm-backdrop{position:fixed;inset:0;z-index:200000;background:#0000008c;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center}.tabs-confirm-dialog{background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 0 -6px 12px #403d4680;border-radius:16px;padding:24px 28px 20px;max-width:340px;width:calc(100vw - 48px);display:flex;flex-direction:column;gap:12px}.tabs-confirm-dialog__title{font-family:Calistoga,serif;font-size:14px;font-weight:400;color:#fff;line-height:1.3}.tabs-confirm-dialog__description{font-family:Gilroy,sans-serif;font-size:11px;font-weight:500;color:#ffffffb3;line-height:1.5}.tabs-confirm-dialog__actions{display:flex;justify-content:flex-end;gap:10px;margin-top:4px}.tabs-confirm-btn{font-family:Gilroy,sans-serif;font-weight:700;font-size:11px;letter-spacing:.07px;border:none;border-radius:8px;padding:8px 18px;cursor:pointer;transition:opacity .2s}.tabs-confirm-btn:hover{opacity:.85}.tabs-confirm-btn--cancel{background:#ffffff1a;color:#ffffffbf}.tabs-confirm-btn--confirm{background:#fe3c72;color:#fff}.tabs-alert-host{position:fixed;top:20px;right:20px;z-index:300000;pointer-events:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i3$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3$2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i3$2.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i3$2.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "component", type: AlertPopupComponent, selector: "lib-alert-popup", inputs: ["title", "description", "timeState", "number"], outputs: ["closed"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i1.PrimaryBtnComponent, selector: "lib-primary-btn", inputs: ["hoverOutline", "disabled", "type", "form", "label", "showArrowIcon", "disableTextShadow", "loading$"] }, { kind: "component", type: i1.SecondaryBtnComponent, selector: "lib-secondary-btn", inputs: ["hoverOutline", "disabled", "type", "form", "label", "showArrowIcon", "disableTextShadow", "loading$"] }, { kind: "ngmodule", type: PopperModule }, { kind: "directive", type: i1.PopperDirective, selector: "[libPopper]", inputs: ["libPopper", "popperTrigger", "popperHideOnClickOutside", "openOnInit"], exportAs: ["libPopper"] }, { kind: "component", type: i1.LibPopperContentComponent, selector: "lib-popper-content", inputs: ["arrowClass", "popperClass", "openOnInit"], outputs: ["visibilityChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6863
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LibDashboardSwipeableTabsComponent, isStandalone: true, selector: "lib-dashboard-swipeable-tabs", inputs: { thumbsSwiperOptions: "thumbsSwiperOptions", mainSwiperOptions: "mainSwiperOptions", activeIndex: "activeIndex", bottomThumbs: "bottomThumbs", slideContentMaxHeight: "slideContentMaxHeight", mainSwiperHeight: "mainSwiperHeight", subMainSwiperHeight: "subMainSwiperHeight", thumbsSwiperHeight: "thumbsSwiperHeight", generalSwiperHeight: "generalSwiperHeight", enableGrouping: "enableGrouping", enableDragAndDrop: "enableDragAndDrop", enableTabBarScrollDrag: "enableTabBarScrollDrag", items: "items", thumbTemplate: "thumbTemplate", contentTemplate: "contentTemplate", groupingAdapter: "groupingAdapter", showPrefRejectButton: "showPrefRejectButton", menuPosition: "menuPosition" }, outputs: { repositionModeChange: "repositionModeChange", activeIndexChange: "activeIndexChange", itemClicked: "itemClicked", expandedIdChange: "expandedIdChange" }, queries: [{ propertyName: "thumbSlides", first: true, predicate: ["thumbSlides"], descendants: true }], viewQueries: [{ propertyName: "thumbSwiper", first: true, predicate: ["thumbSwiper"], descendants: true }, { propertyName: "mainSwiper", first: true, predicate: ["mainSwiper"], descendants: true }, { propertyName: "settingsTriggerWrapperEl", first: true, predicate: ["settingsTriggerWrapperEl"], descendants: true }, { propertyName: "settingsTriggerPortalTemplate", first: true, predicate: ["settingsTriggerPortalTemplate"], descendants: true }, { propertyName: "contextMenuTemplate", first: true, predicate: ["contextMenuTemplate"], descendants: true }, { propertyName: "confirmDialogTemplate", first: true, predicate: ["confirmDialogTemplate"], descendants: true }, { propertyName: "alertTemplate", first: true, predicate: ["alertTemplate"], descendants: true }, { propertyName: "tabBarContainer", first: true, predicate: ["tabBarContainer"], descendants: true }, { propertyName: "expandedPortalTemplate", first: true, predicate: ["expandedPortalTemplate"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"swipeable-tabs-container\"\n [class.bottom-thumbs]=\"bottomThumbs\"\n [ngStyle]=\"{ height: generalSwiperHeight }\"\n [style.--thumbs-height]=\"thumbsSwiperHeight\"\n>\n\n <!-- \u2500\u2500 LEGACY MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (!enableGrouping) {\n <ng-container>\n <swiper-container #thumbSwiper init=\"false\" class=\"thumb-swiper container-sides-shadow\" [ngStyle]=\"{ height: thumbsSwiperHeight }\">\n <ng-content select=\"[thumb-slides]\"></ng-content>\n </swiper-container>\n <div class=\"swiper-container main-swiper\" [style.max-height]=\"slideContentMaxHeight\" [ngStyle]=\"{ height: mainSwiperHeight }\">\n <swiper-container #mainSwiper init=\"false\" class=\"main-swiper\" [class.container-sides-shadow]=\"activeIndex !== 0\" [ngStyle]=\"{ height: subMainSwiperHeight }\">\n <ng-content select=\"[main-slides]\"></ng-content>\n </swiper-container>\n </div>\n </ng-container>\n }\n\n <!-- \u2500\u2500 GROUPING MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (enableGrouping) {\n <ng-container>\n\n <!-- Settings trigger -->\n <div class=\"settings-trigger-wrapper\" #settingsTriggerWrapperEl>\n <div class=\"settings-trigger\" [class.settings-trigger--hidden]=\"settingsTriggerPortaled\" (click)=\"toggleGlobalMenu($event)\">\n <i class=\"pi pi-cog\"></i>\n </div>\n @if (showGlobalMenu) {\n <div class=\"global-menu\" [ngClass]=\"'menu-' + menuPosition\" (click)=\"$event.stopPropagation()\">\n <div class=\"menu-item\" (click)=\"requestGroupBy('response')\">Group by Response</div>\n <div class=\"menu-item\" (click)=\"requestGroupBy('client')\">Group by Client</div>\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"restoreCustomGroups()\">Restore Custom Groups</div>\n <div class=\"menu-item\" (click)=\"storeCustomGroups()\">Store Custom Groups</div>\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"ungroupAll()\">Ungroup All</div>\n </div>\n }\n </div>\n\n <ng-template #settingsTriggerPortalTemplate>\n <div\n class=\"settings-trigger-wrapper settings-trigger-wrapper-portal\"\n [style.left.px]=\"settingsTriggerPortalLeft\"\n [style.top.px]=\"settingsTriggerPortalTop\"\n >\n <div class=\"settings-trigger\" (click)=\"toggleGlobalMenu($event)\">\n <i class=\"pi pi-cog\"></i>\n </div>\n </div>\n </ng-template>\n\n <!-- Tab Bar -->\n <div class=\"tab-bar-container\"\n #tabBarContainer\n cdkScrollable\n [class.dragging-active]=\"isDragging\"\n [class.grouping-animating]=\"groupingAnimating\"\n [class.grab-cursor]=\"!repositionMode && !isScrollDragging\"\n [class.grabbing-cursor]=\"isScrollDragging\"\n [ngStyle]=\"{ minHeight: thumbsSwiperHeight }\"\n tabindex=\"0\">\n\n <div\n cdkDropList\n [id]=\"rootDropListId\"\n [cdkDropListConnectedTo]=\"connectedDropLists\"\n [cdkDropListEnterPredicate]=\"canDropToRoot\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"tabNodes\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"tab-list-root\">\n\n @for (node of tabNodes; track trackByNode($index, node); let i = $index) {\n <div cdkDrag\n [cdkDragData]=\"node\"\n [cdkDragDisabled]=\"!enableDragAndDrop || isRootNodeDragDisabled(node)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"dragEnded($event)\"\n class=\"tab-node-wrapper\"\n [class.potential-group-target]=\"isItem(node) && potentialGroupTargetId === getSafeId(node.data)\"\n [attr.data-id]=\"isItem(node) ? getSafeId(node.data) : null\"\n (mousedown)=\"onNodeDown($event)\"\n (touchstart)=\"onNodeDown($event)\"\n (mouseup)=\"onNodeMouseUp()\"\n (touchend)=\"onNodeMouseUp()\">\n\n <div *cdkDragPreview>\n <ng-container *ngTemplateOutlet=\"nodePreviewTemplate; context: { node: node }\"></ng-container>\n </div>\n <div *cdkDragPlaceholder [class.reposition-placeholder]=\"repositionMode\"></div>\n\n <!-- \u2500\u2500 Case 1: Ungrouped Item \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (isItem(node)) {\n <ng-container>\n <div class=\"tab-item ungrouped\"\n [class.is-expanded-source]=\"expandedItemId === getSafeId(node.data)\"\n [attr.data-expanded-id]=\"expandedItemId === getSafeId(node.data) ? expandedItemId : null\"\n [class.active]=\"displayItems.indexOf(node.data) === activeIndex\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(node.data)\"\n (click)=\"onItemClick($event, node)\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: false, expanded: false }\"></ng-container>\n </div>\n\n @if (potentialGroupTargetId === getSafeId(node.data)) {\n <div class=\"visual-group-wrapper\">\n <div class=\"group-header-vertical\"></div>\n <div class=\"group-list-visual\">\n <div class=\"tab-item\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: true, expanded: false }\"></ng-container>\n </div>\n <div class=\"tab-item ghost-item\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: draggedItemData?.data, grouped: true, expanded: false }\"></ng-container>\n </div>\n </div>\n </div>\n }\n </ng-container>\n }\n\n <!-- \u2500\u2500 Case 2: Group Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (isGroup(node)) {\n <ng-container>\n <div class=\"group-container\"\n [class.collapsed]=\"node.data.collapsed\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(node.data)\"\n [class.pulsating-group]=\"repositionMode && repositionTargetId === getSafeId(node.data)\"\n [style.border-color]=\"node.data.color\"\n [style.--group-accent-color]=\"node.data.color\"\n cdkDragHandle\n [cdkDragHandleDisabled]=\"!enableDragAndDrop || isRootNodeDragDisabled(node) || repositionTargetGroupId === node.id\"\n (mousedown)=\"onNodeDown($event)\"\n (touchstart)=\"onNodeDown($event)\"\n (mouseup)=\"onNodeMouseUp()\"\n (touchend)=\"onNodeMouseUp()\">\n\n <div class=\"group-header-vertical\" (click)=\"toggleGroup(node.data)\">\n <div class=\"group-title-vertical\">\n <span class=\"group-title-text\">{{ getTruncatedTitle(node.data.title, node.data.collapsed) }}</span>\n </div>\n <div class=\"group-ellipsis-vertical\"\n (click)=\"openContextMenu($event, node); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n (touchstart)=\"$event.stopPropagation()\">\n <div class=\"group-ellipsis-dot\"></div>\n <div class=\"group-ellipsis-dot\"></div>\n <div class=\"group-ellipsis-dot\"></div>\n </div>\n </div>\n\n <div cdkDropList\n [id]=\"'group-list-' + getSafeId(node.data)\"\n [cdkDropListConnectedTo]=\"connectedDropLists\"\n [cdkDropListData]=\"node.data.items\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListEnterPredicate]=\"canDropToGroup\"\n cdkDropListOrientation=\"horizontal\"\n class=\"group-list\"\n [class.collapsed-drop-target]=\"node.data.collapsed && isDragging\">\n\n @for (item of node.data.items; track trackByItem($index, item)) {\n <div class=\"tab-item\"\n cdkDrag\n [class.is-expanded-source]=\"expandedItemId === getSafeId(item)\"\n [attr.data-expanded-id]=\"expandedItemId === getSafeId(item) ? expandedItemId : null\"\n [cdkDragData]=\"{ type: 'item', data: item }\"\n [cdkDragDisabled]=\"!enableDragAndDrop || isItemDragDisabled(getSafeId(item), node.id)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"dragEnded($event)\"\n [class.active]=\"displayItems.indexOf(item) === activeIndex\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(item)\"\n (click)=\"onItemClick($event, { type: 'item', data: item, id: getSafeId(item) })\">\n\n <div *cdkDragPreview>\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item, grouped: true, expanded: false }\"></ng-container>\n </div>\n <div *cdkDragPlaceholder [class.reposition-placeholder]=\"repositionMode\"></div>\n\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item, grouped: true, expanded: false }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </ng-container>\n }\n </div>\n }\n\n <!-- Drag preview template -->\n <ng-template #nodePreviewTemplate let-node=\"node\">\n @if (isItem(node)) {\n <div class=\"tab-item ungrouped\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: false, expanded: false }\"></ng-container>\n </div>\n }\n @if (isGroup(node)) {\n <div class=\"group-container collapsed\"\n [style.border-color]=\"node.data.color\"\n [style.--group-accent-color]=\"node.data.color\">\n <div class=\"group-header-vertical\">\n <div class=\"group-title-vertical\">\n <span class=\"group-title-text\">{{ getTruncatedTitle(node.data.title, true) }}</span>\n </div>\n </div>\n </div>\n }\n </ng-template>\n\n </div>\n </div>\n\n <ng-template #expandedPortalTemplate>\n @if (expandedItemId && portalRect && !(isDragging && getSafeId(draggedItemData?.data) === expandedItemId)) {\n <div class=\"expanded-item-portal\"\n [attr.data-expanded-portal-id]=\"expandedItemId\"\n [style.left.px]=\"portalRect.left\"\n [style.top.px]=\"portalRect.top\"\n [style.width.px]=\"portalRect.width\"\n (pointerdown)=\"onScrollPointerDown($event)\"\n (mousedown)=\"onPortalDown($event)\"\n (touchstart)=\"onPortalDown($event)\"\n (click)=\"onPortalClick($event)\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: expandedItemRef, grouped: false, expanded: true }\"></ng-container>\n </div>\n }\n </ng-template>\n\n @if (showPrefRejectButton) {\n <button type=\"button\" class=\"tabs-pref-reject-button\">\n <span class=\"tabs-pref-reject-button__icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\">\n <g>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M10.9353 4.11938C11.1384 4.3225 11.1384 4.65183 10.9353 4.85495L2.35324 13.437C2.15012 13.6401 1.82079 13.6401 1.61767 13.437C1.41455 13.2339 1.41455 12.9046 1.61767 12.7014L10.1997 4.11938C10.4028 3.91626 10.7322 3.91626 10.9353 4.11938Z\" fill=\"#FE3C72\"/>\n <circle cx=\"6.14645\" cy=\"8.64816\" r=\"4.0\" stroke=\"#FE3C72\" stroke-width=\"1\"/>\n </g>\n </svg>\n </span>\n <span class=\"tabs-pref-reject-button__label\">Reject</span>\n </button>\n }\n\n <!-- Global menu overlay -->\n @if (showGlobalMenu) {\n <div class=\"global-menu-overlay\" (click)=\"toggleGlobalMenu($event)\"></div>\n }\n\n <!-- Context menu overlay -->\n @if (activeContextMenuNode) {\n <div class=\"context-menu-overlay\" (click)=\"closeMenus()\"></div>\n }\n\n <!-- \u2500\u2500 Context menu (portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #contextMenuTemplate>\n @if (activeContextMenuNode) {\n <div class=\"context-menu\"\n [style.left.px]=\"contextMenuPosition.x\"\n [style.top.px]=\"contextMenuPosition.y\"\n style=\"position: fixed; z-index: 100000;\">\n @if (activeContextMenuNode?.type === 'group' || activeContextMenuNode?.type === 'item') {\n <div class=\"menu-item\" (click)=\"toggleRepositionMode()\">\n {{ repositionMode && (!repositionTargetId || repositionTargetId === getSafeId(activeContextMenuNode?.data)) ? 'End Reposition' : 'Reposition' }}\n </div>\n }\n @if (activeContextMenuNode?.type === 'group') {\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"handleMenuAction('ungroup', activeContextMenuNode!)\">Ungroup</div>\n }\n </div>\n }\n </ng-template>\n\n <!-- \u2500\u2500 Confirmation dialog (Portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #confirmDialogTemplate>\n <div class=\"confirm-dialog-overlay\" (click)=\"cancelGroupBy()\">\n <div class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"m-title f-w-700 f-lg h-160 f-white\">Overwrite Manual Groups?</div>\n <span class=\"message f-w-400 f-md h-150 f-gray\">\n This operation will discard your current manual arrangement.\n Continue?\n </span>\n <div class=\"buttons\">\n <lib-secondary-btn (click)=\"cancelGroupBy()\" type=\"button\">Cancel</lib-secondary-btn>\n <lib-primary-btn (click)=\"confirmGroupBy()\" type=\"button\">Continue</lib-primary-btn>\n </div>\n </div>\n </div>\n </ng-template>\n\n <!-- \u2500\u2500 Alert / Toastr (portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #alertTemplate>\n <div class=\"tabs-alert-host\">\n <lib-alert-popup\n [title]=\"alertTitle\"\n [description]=\"alertDescription\"\n [timeState]=\"alertTimeState\"\n (closed)=\"dismissAlert()\">\n </lib-alert-popup>\n </div>\n </ng-template>\n\n <!-- Main Content Swiper -->\n <div class=\"swiper-container main-swiper\" [style.max-height]=\"slideContentMaxHeight\" [ngStyle]=\"{ height: mainSwiperHeight }\">\n <swiper-container #mainSwiper init=\"false\" class=\"main-swiper\"\n [class.container-sides-shadow]=\"activeIndex !== 0\"\n [ngStyle]=\"{ height: subMainSwiperHeight }\">\n @for (item of displayItems; track trackByItem($index, item)) {\n <swiper-slide>\n <ng-container *ngTemplateOutlet=\"contentTemplate; context: { $implicit: item, index: $index }\"></ng-container>\n </swiper-slide>\n }\n </swiper-container>\n </div>\n\n </ng-container>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;min-width:0;height:100%;display:flex;flex-direction:column;padding-top:0;font-family:Gilroy,sans-serif}.swipeable-tabs-container{position:relative;display:flex;width:100%;height:100%;min-height:0;flex-direction:column;flex:1}.swipeable-tabs-container.bottom-thumbs{flex-direction:column-reverse}.swipeable-tabs-container>.main-swiper{flex:1;display:flex;flex-direction:column;z-index:100}.swipeable-tabs-container swiper-container{position:relative;display:block;overflow:auto;width:100%;height:100%}.swipeable-tabs-container swiper-container{scrollbar-width:none}.swipeable-tabs-container swiper-container::-webkit-scrollbar{display:none}.expanded-item-portal{position:fixed;transform:translate(-50%,-50%);z-index:1000;pointer-events:auto}.settings-trigger-wrapper{position:absolute;top:-15px;right:0;z-index:3000;pointer-events:none}.settings-trigger-wrapper.settings-trigger-wrapper-portal{position:fixed;top:0;right:auto;z-index:3000;pointer-events:none}.settings-trigger{padding:8px;cursor:pointer;color:#fffc;transition:all .3s ease;pointer-events:auto;display:flex;align-items:center;justify-content:center;background:transparent;background:radial-gradient(circle,rgba(0,0,0,.9) 0%,transparent 70%);box-shadow:none;border:none;border-radius:50%}.settings-trigger:hover{color:#fff;background:radial-gradient(circle,rgba(0,0,0,.95) 0%,transparent 70%)}.settings-trigger i{font-size:1.5rem;filter:drop-shadow(0px 0px 2px rgba(0,0,0,.8))}.settings-trigger.settings-trigger--hidden{visibility:hidden;pointer-events:none}.global-menu-overlay,.context-menu-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2000;background:transparent}.confirm-dialog-overlay{position:fixed;inset:0;width:100vw;height:100vh;z-index:100000;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:24px;pointer-events:auto}.confirm-dialog{width:min(420px,100%);background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border-radius:13px;padding:16px;pointer-events:auto}.confirm-dialog .buttons{display:flex;justify-content:flex-end;gap:12px;margin-top:16px}.global-menu{position:absolute;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border:none;border-radius:13px;padding:5px 0;min-width:150px;z-index:3001;display:flex;flex-direction:column;overflow:hidden;right:0;left:auto;pointer-events:auto}.menu-up{top:auto;bottom:100%;margin-bottom:10px;margin-top:0;transform-origin:bottom right;animation:fadeIn .2s ease-out}.menu-down{top:100%;bottom:auto;margin-top:10px;margin-bottom:0;transform-origin:top right;animation:fadeInDown .2s ease-out}.context-menu{position:fixed;margin-left:-17px;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border:none;border-radius:13px;padding:5px 0;min-width:150px;z-index:1002;display:flex;flex-direction:column;overflow:hidden}.context-menu{animation:scaleIn .15s ease-out}.menu-item{padding:12px 20px;color:#ffffffe6;font-family:Gilroy,sans-serif;font-weight:700;font-size:11px;line-height:100%;letter-spacing:.07px;vertical-align:middle;cursor:pointer;transition:background .2s;white-space:nowrap;display:flex;align-items:center}.menu-item:hover{background:#ffffff1a}.global-menu .menu-item{justify-content:flex-end;text-align:right;padding-right:20px}.context-menu .menu-item{justify-content:flex-start;text-align:left;padding-left:20px}.menu-separator{height:1px;background:linear-gradient(to right,transparent,rgba(255,255,255,.3),transparent);margin:8px auto;width:50%}.global-menu .menu-separator{margin-left:auto;margin-right:10%}.context-menu .menu-separator{margin-right:auto;margin-left:10%}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes scaleIn{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}.item-ellipsis{cursor:pointer;color:#ffffff80;padding:2px;border-radius:50%;transition:all .2s}.item-ellipsis:hover{color:#fff;background:#ffffff1a}.item-ellipsis i{font-size:.9rem}.tab-item{width:54px;min-width:27px;height:54px;display:flex;align-items:center;justify-content:center;line-height:0}.tab-item img,.tab-item .avatar{width:auto;height:auto;object-fit:cover;border-radius:50%;margin:0}.tab-item.is-expanded-source{visibility:hidden;min-width:174px!important;flex-shrink:0}.tab-item.expanded-item{height:auto!important;width:auto!important}.tab-item.ungrouped{position:relative}.tab-item.ungrouped .item-ellipsis{position:absolute;bottom:0;right:0;z-index:10;background:#00000080}.tab-bar-container{display:flex;flex-direction:row;overflow-x:auto;overflow-y:hidden;width:100%;max-width:100%;min-width:0;flex-shrink:0;position:relative;z-index:1000;pointer-events:auto;-ms-overflow-style:none;scrollbar-width:none}.tab-bar-container:focus{outline:none}.tab-bar-container.grab-cursor{cursor:grab}.tab-bar-container.grabbing-cursor{cursor:grabbing;-webkit-user-select:none;user-select:none}.tab-bar-container::-webkit-scrollbar{display:none}.tab-bar-container.grouping-animating .cdk-drag-animating{transition:none!important}.tab-bar-container.grouping-animating .tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder){transition:none!important}.tab-bar-container.grouping-animating .cdk-drag-preview{display:none!important}.tabs-pref-reject-button{position:absolute;left:30%;transform:translate(-50%);bottom:calc(var(--thumbs-height, 40px) + 5px);display:inline-flex;align-items:center;gap:6px;padding:0 10px;height:29px;border:none;border-radius:8px;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 2px 4px #00000040,0 4px 4px #00000040,2px -2px 3px #0006 inset,0 -2px 8px #fff3 inset;color:#d9d9d9;font-family:Gilroy,sans-serif;font-size:8px;letter-spacing:.07px;cursor:pointer;z-index:1100}.tabs-pref-reject-button__icon{display:flex;align-items:center;justify-content:center}.tabs-pref-reject-button__label{line-height:1}.tab-list-root{display:flex;flex-direction:row;align-items:center;gap:10px;padding:0 100px 0 20px;min-width:100%;width:max-content;flex-shrink:0;flex-grow:1;height:100%}.tab-list-root .cdk-drag-placeholder{width:2px!important;min-width:2px!important;height:40px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;flex:0 0 auto;visibility:visible!important}.tab-node-wrapper{display:flex;align-items:center;flex-shrink:0;pointer-events:auto;position:relative;z-index:2;width:auto;min-width:min-content}.cdk-drag-preview{box-sizing:border-box;border-radius:0;box-shadow:none;z-index:9999!important;opacity:.5;width:auto;height:auto;display:inline-flex;align-items:center;justify-content:center;overflow:visible;pointer-events:none;scrollbar-width:none}.cdk-drag-preview::-webkit-scrollbar{display:none}.recently-dropped{opacity:.5;animation:fadeBackIn 1s ease-in forwards;animation-delay:2s}@keyframes fadeBackIn{0%{opacity:.5}to{opacity:1}}.cdk-drag-placeholder{opacity:0}.hidden-placeholder~.cdk-drag-preview,.tab-node-wrapper:has(.hidden-placeholder){transition:none!important}.tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.group-container{border:none;position:relative;display:flex;flex-direction:row;align-items:flex-start;padding:0 0 0 4px;box-sizing:border-box;isolation:isolate;margin-right:20px;background:transparent;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 8px 32px #0000005e,inset 0 1px #ffffff4d;border-radius:9px;overflow:visible;transition:all .3s ease}.group-container.pulsating-group{animation:pulsate-group-border 1.5s infinite}.group-container:before{content:\"\";position:absolute;inset:0 auto 0 0;width:min(45px,50%);background:linear-gradient(to right,var(--group-accent-color, rgba(255, 255, 255, .1)),transparent);opacity:.6;filter:blur(15px);z-index:0;pointer-events:none;border-radius:inherit;clip-path:inset(0 0 0 0 round 9px)}.group-container:not(:has(.tab-item.is-expanded-source)){overflow:hidden}.group-container:has(.tab-item.is-expanded-source){overflow:visible;z-index:50}.group-container:has(.tab-item.is-expanded-source):before{clip-path:inset(0 0 0 0 round 9px);overflow:hidden}.group-container.collapsed{width:auto;max-width:none;padding-left:2px}.group-container.collapsed .group-list,.group-container.collapsed .group-ellipsis-vertical{display:none}.group-container.collapsed:before{width:min(32px,30%)}.group-container:has(.tab-item.expanded-item){overflow:visible;z-index:50}@keyframes pulsate-group-border{0%{box-shadow:0 0 #ffffffb3,0 8px 32px #0000005e,inset 0 1px #ffffff4d}70%{box-shadow:0 0 0 6px #fff0,0 8px 32px #0000005e,inset 0 1px #ffffff4d}to{box-shadow:0 0 #fff0,0 8px 32px #0000005e,inset 0 1px #ffffff4d}}.group-title-text{font-family:Calistoga,serif;font-weight:400;font-style:normal;font-size:10px;line-height:100%;letter-spacing:0%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff6;max-height:40px;text-align:center;width:100%;display:block;margin-top:6px}.group-header-vertical{width:30px;align-self:stretch;display:flex;flex-direction:column;padding:0 2px;cursor:grab;z-index:20;position:relative;height:54px;max-height:54px;background:transparent}.group-header-vertical:before{content:\"\";position:absolute;inset:0;background:linear-gradient(to right,var(--group-accent-color, rgba(255, 255, 255, .1)),transparent);opacity:.5;filter:blur(4px);z-index:-1}.group-header-vertical>*{position:relative;z-index:1}.group-container.collapsed{border-radius:13px}.group-container.collapsed .group-header-vertical{justify-content:center;align-items:center;width:18px}.group-container.collapsed .group-title-text{margin-bottom:5px;text-align:center}.group-container:not(.collapsed) .group-header-vertical{justify-content:space-around;align-items:flex-start;padding-left:0;padding-bottom:0;padding-top:0}.group-title-vertical{display:flex;align-items:center;justify-content:center;writing-mode:vertical-rl;transform:rotate(180deg);padding:0;margin-bottom:0;overflow:hidden;min-height:40px}.group-ellipsis-vertical{cursor:pointer;align-items:center;justify-content:space-between;width:100%;height:auto;position:static;margin:-11px 0 0;padding-left:0;display:flex;justify-content:flex-start;gap:3px;padding-bottom:5px}.group-ellipsis-vertical:hover{opacity:.7}.group-ellipsis-vertical .group-ellipsis-dot{width:3px;height:3px;background-color:#fff;border-radius:50%!important;display:block}.tab-bar-container.dragging-active .group-header-vertical{z-index:1;pointer-events:none}.group-list{padding-top:2px;display:flex;align-items:center;justify-content:space-around;min-width:40px;margin-left:-13.5px;margin-right:-11.5px;margin-top:-7.5px;gap:20px;border-radius:4px;position:relative;z-index:1;pointer-events:auto}.group-list .tab-item.is-expanded-source,.group-list .tab-item.is-expanded-source.cdk-drag-placeholder{min-width:174px!important;visibility:visible!important;opacity:.5}.group-list.collapsed-drop-target{position:absolute;top:0;left:0;width:100%;height:100%;min-width:unset;background:#ffffff4d;border:2px dashed rgba(255,255,255,.8);z-index:50;border-radius:16px}.group-list.collapsed-drop-target .tab-item{display:none}.reposition-placeholder{width:2px!important;min-width:2px!important;height:40px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;border:none;box-shadow:none;flex:0 0 auto}.group-list .cdk-drag-placeholder{width:2px!important;min-width:2px!important;height:46px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;border:none;box-shadow:0 0 6px 2px #fe3c7299!important;flex:0 0 auto;visibility:visible!important}.hidden-placeholder{visibility:hidden!important;pointer-events:none!important}.tab-node-wrapper.potential-group-target .tab-item.ungrouped{display:none}.visual-group-wrapper{border:none;display:flex;flex-direction:row;align-items:flex-start;padding:3px 3px 3px 4px;background:transparent;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 8px 32px #0000005e,inset 0 1px #ffffff4d;border-radius:9px;overflow:hidden;border:1px solid rgba(255,255,255,.2)}.visual-group-wrapper .group-header-vertical{width:18px;height:54px;background:#ffffff1a}.visual-group-wrapper .group-list-visual{display:flex;align-items:center;justify-content:space-around;gap:4.5px;margin-left:-4px;padding-top:2px}.visual-group-wrapper .ghost-item{opacity:.3;filter:grayscale(100%)}.grabbing-cursor{cursor:grabbing!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder),.group-list.cdk-drop-list-dragging .tab-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.05)}to{transform:scale(1)}}.tabs-confirm-backdrop{position:fixed;inset:0;z-index:200000;background:#0000008c;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center}.tabs-confirm-dialog{background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 0 -6px 12px #403d4680;border-radius:16px;padding:24px 28px 20px;max-width:340px;width:calc(100vw - 48px);display:flex;flex-direction:column;gap:12px}.tabs-confirm-dialog__title{font-family:Calistoga,serif;font-size:14px;font-weight:400;color:#fff;line-height:1.3}.tabs-confirm-dialog__description{font-family:Gilroy,sans-serif;font-size:11px;font-weight:500;color:#ffffffb3;line-height:1.5}.tabs-confirm-dialog__actions{display:flex;justify-content:flex-end;gap:10px;margin-top:4px}.tabs-confirm-btn{font-family:Gilroy,sans-serif;font-weight:700;font-size:11px;letter-spacing:.07px;border:none;border-radius:8px;padding:8px 18px;cursor:pointer;transition:opacity .2s}.tabs-confirm-btn:hover{opacity:.85}.tabs-confirm-btn--cancel{background:#ffffff1a;color:#ffffffbf}.tabs-confirm-btn--confirm{background:#fe3c72;color:#fff}.tabs-alert-host{position:fixed;top:20px;right:20px;z-index:300000;pointer-events:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i3$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3$2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i3$2.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i3$2.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "component", type: AlertPopupComponent, selector: "lib-alert-popup", inputs: ["title", "description", "timeState", "number"], outputs: ["closed"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i1.PrimaryBtnComponent, selector: "lib-primary-btn", inputs: ["hoverOutline", "disabled", "type", "form", "label", "showArrowIcon", "disableTextShadow", "loading$"] }, { kind: "component", type: i1.SecondaryBtnComponent, selector: "lib-secondary-btn", inputs: ["hoverOutline", "disabled", "type", "form", "label", "showArrowIcon", "disableTextShadow", "loading$"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6798
6864
|
}
|
|
6799
6865
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LibDashboardSwipeableTabsComponent, decorators: [{
|
|
6800
6866
|
type: Component,
|
|
6801
|
-
args: [{ selector: 'lib-dashboard-swipeable-tabs', imports: [CommonModule, TranslateModule, DragDropModule, CdkScrollable, AlertPopupComponent, ButtonsModule, PopperModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"swipeable-tabs-container\"\n [class.bottom-thumbs]=\"bottomThumbs\"\n [ngStyle]=\"{ height: generalSwiperHeight }\"\n [style.--thumbs-height]=\"thumbsSwiperHeight\"\n>\n\n <!-- \u2500\u2500 LEGACY MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (!enableGrouping) {\n <ng-container>\n <swiper-container #thumbSwiper init=\"false\" class=\"thumb-swiper container-sides-shadow\" [ngStyle]=\"{ height: thumbsSwiperHeight }\">\n <ng-content select=\"[thumb-slides]\"></ng-content>\n </swiper-container>\n <div class=\"swiper-container main-swiper\" [style.max-height]=\"slideContentMaxHeight\" [ngStyle]=\"{ height: mainSwiperHeight }\">\n <swiper-container #mainSwiper init=\"false\" class=\"main-swiper\" [class.container-sides-shadow]=\"activeIndex !== 0\" [ngStyle]=\"{ height: subMainSwiperHeight }\">\n <ng-content select=\"[main-slides]\"></ng-content>\n </swiper-container>\n </div>\n </ng-container>\n }\n\n <!-- \u2500\u2500 GROUPING MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (enableGrouping) {\n <ng-container>\n\n <!-- Settings trigger -->\n <div class=\"settings-trigger-wrapper\" #settingsTriggerWrapperEl>\n <div class=\"settings-trigger\" [class.settings-trigger--hidden]=\"settingsTriggerPortaled\" (click)=\"toggleGlobalMenu($event)\" [libPopper]=\"confirmPopper\" [popperTrigger]=\"'none'\">\n <i class=\"pi pi-cog\"></i>\n </div>\n @if (showGlobalMenu) {\n <div class=\"global-menu\" [ngClass]=\"'menu-' + menuPosition\" (click)=\"$event.stopPropagation()\">\n <div class=\"menu-item\" (click)=\"requestGroupBy('response')\">Group by Response</div>\n <div class=\"menu-item\" (click)=\"requestGroupBy('client')\">Group by Client</div>\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"restoreCustomGroups()\">Restore Custom Groups</div>\n <div class=\"menu-item\" (click)=\"storeCustomGroups()\">Store Custom Groups</div>\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"ungroupAll()\">Ungroup All</div>\n </div>\n }\n </div>\n\n <ng-template #settingsTriggerPortalTemplate>\n <div\n class=\"settings-trigger-wrapper settings-trigger-wrapper-portal\"\n [style.left.px]=\"settingsTriggerPortalLeft\"\n [style.top.px]=\"settingsTriggerPortalTop\"\n >\n <div class=\"settings-trigger\" (click)=\"toggleGlobalMenu($event)\" [libPopper]=\"confirmPopper\" [popperTrigger]=\"'none'\">\n <i class=\"pi pi-cog\"></i>\n </div>\n </div>\n </ng-template>\n\n <!-- Tab Bar -->\n <div class=\"tab-bar-container\"\n #tabBarContainer\n cdkScrollable\n [class.dragging-active]=\"isDragging\"\n [class.grouping-animating]=\"groupingAnimating\"\n [class.grab-cursor]=\"!repositionMode && !isScrollDragging\"\n [class.grabbing-cursor]=\"isScrollDragging\"\n [ngStyle]=\"{ minHeight: thumbsSwiperHeight }\"\n tabindex=\"0\">\n\n <div\n cdkDropList\n [id]=\"rootDropListId\"\n [cdkDropListConnectedTo]=\"connectedDropLists\"\n [cdkDropListEnterPredicate]=\"canDropToRoot\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"tabNodes\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"tab-list-root\">\n\n @for (node of tabNodes; track trackByNode($index, node); let i = $index) {\n <div cdkDrag\n [cdkDragData]=\"node\"\n [cdkDragDisabled]=\"!enableDragAndDrop || isRootNodeDragDisabled(node)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"dragEnded($event)\"\n class=\"tab-node-wrapper\"\n [class.potential-group-target]=\"isItem(node) && potentialGroupTargetId === getSafeId(node.data)\"\n [attr.data-id]=\"isItem(node) ? getSafeId(node.data) : null\"\n (mousedown)=\"onNodeDown($event)\"\n (touchstart)=\"onNodeDown($event)\"\n (mouseup)=\"onNodeMouseUp()\"\n (touchend)=\"onNodeMouseUp()\">\n\n <div *cdkDragPreview>\n <ng-container *ngTemplateOutlet=\"nodePreviewTemplate; context: { node: node }\"></ng-container>\n </div>\n <div *cdkDragPlaceholder [class.reposition-placeholder]=\"repositionMode\"></div>\n\n <!-- \u2500\u2500 Case 1: Ungrouped Item \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (isItem(node)) {\n <ng-container>\n <div class=\"tab-item ungrouped\"\n [class.is-expanded-source]=\"expandedItemId === getSafeId(node.data)\"\n [attr.data-expanded-id]=\"expandedItemId === getSafeId(node.data) ? expandedItemId : null\"\n [class.active]=\"displayItems.indexOf(node.data) === activeIndex\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(node.data)\"\n (click)=\"onItemClick($event, node)\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: false, expanded: false }\"></ng-container>\n </div>\n\n @if (potentialGroupTargetId === getSafeId(node.data)) {\n <div class=\"visual-group-wrapper\">\n <div class=\"group-header-vertical\"></div>\n <div class=\"group-list-visual\">\n <div class=\"tab-item\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: true, expanded: false }\"></ng-container>\n </div>\n <div class=\"tab-item ghost-item\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: draggedItemData?.data, grouped: true, expanded: false }\"></ng-container>\n </div>\n </div>\n </div>\n }\n </ng-container>\n }\n\n <!-- \u2500\u2500 Case 2: Group Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (isGroup(node)) {\n <ng-container>\n <div class=\"group-container\"\n [class.collapsed]=\"node.data.collapsed\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(node.data)\"\n [class.pulsating-group]=\"repositionMode && repositionTargetId === getSafeId(node.data)\"\n [style.border-color]=\"node.data.color\"\n [style.--group-accent-color]=\"node.data.color\"\n cdkDragHandle\n [cdkDragHandleDisabled]=\"!enableDragAndDrop || isRootNodeDragDisabled(node) || repositionTargetGroupId === node.id\"\n (mousedown)=\"onNodeDown($event)\"\n (touchstart)=\"onNodeDown($event)\"\n (mouseup)=\"onNodeMouseUp()\"\n (touchend)=\"onNodeMouseUp()\">\n\n <div class=\"group-header-vertical\" (click)=\"toggleGroup(node.data)\">\n <div class=\"group-title-vertical\">\n <span class=\"group-title-text\">{{ getTruncatedTitle(node.data.title, node.data.collapsed) }}</span>\n </div>\n <div class=\"group-ellipsis-vertical\"\n (click)=\"openContextMenu($event, node); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n (touchstart)=\"$event.stopPropagation()\">\n <div class=\"group-ellipsis-dot\"></div>\n <div class=\"group-ellipsis-dot\"></div>\n <div class=\"group-ellipsis-dot\"></div>\n </div>\n </div>\n\n <div cdkDropList\n [id]=\"'group-list-' + getSafeId(node.data)\"\n [cdkDropListConnectedTo]=\"connectedDropLists\"\n [cdkDropListData]=\"node.data.items\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListEnterPredicate]=\"canDropToGroup\"\n cdkDropListOrientation=\"horizontal\"\n class=\"group-list\"\n [class.collapsed-drop-target]=\"node.data.collapsed && isDragging\">\n\n @for (item of node.data.items; track trackByItem($index, item)) {\n <div class=\"tab-item\"\n cdkDrag\n [class.is-expanded-source]=\"expandedItemId === getSafeId(item)\"\n [attr.data-expanded-id]=\"expandedItemId === getSafeId(item) ? expandedItemId : null\"\n [cdkDragData]=\"{ type: 'item', data: item }\"\n [cdkDragDisabled]=\"!enableDragAndDrop || isItemDragDisabled(getSafeId(item), node.id)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"dragEnded($event)\"\n [class.active]=\"displayItems.indexOf(item) === activeIndex\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(item)\"\n (click)=\"onItemClick($event, { type: 'item', data: item, id: getSafeId(item) })\">\n\n <div *cdkDragPreview>\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item, grouped: true, expanded: false }\"></ng-container>\n </div>\n <div *cdkDragPlaceholder [class.reposition-placeholder]=\"repositionMode\"></div>\n\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item, grouped: true, expanded: false }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </ng-container>\n }\n </div>\n }\n\n <!-- Drag preview template -->\n <ng-template #nodePreviewTemplate let-node=\"node\">\n @if (isItem(node)) {\n <div class=\"tab-item ungrouped\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: false, expanded: false }\"></ng-container>\n </div>\n }\n @if (isGroup(node)) {\n <div class=\"group-container collapsed\"\n [style.border-color]=\"node.data.color\"\n [style.--group-accent-color]=\"node.data.color\">\n <div class=\"group-header-vertical\">\n <div class=\"group-title-vertical\">\n <span class=\"group-title-text\">{{ getTruncatedTitle(node.data.title, true) }}</span>\n </div>\n </div>\n </div>\n }\n </ng-template>\n\n </div>\n </div>\n\n <ng-template #expandedPortalTemplate>\n @if (expandedItemId && portalRect && !(isDragging && getSafeId(draggedItemData?.data) === expandedItemId)) {\n <div class=\"expanded-item-portal\"\n [attr.data-expanded-portal-id]=\"expandedItemId\"\n [style.left.px]=\"portalRect.left\"\n [style.top.px]=\"portalRect.top\"\n [style.width.px]=\"portalRect.width\"\n (pointerdown)=\"onScrollPointerDown($event)\"\n (mousedown)=\"onPortalDown($event)\"\n (touchstart)=\"onPortalDown($event)\"\n (click)=\"onPortalClick($event)\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: expandedItemRef, grouped: false, expanded: true }\"></ng-container>\n </div>\n }\n </ng-template>\n\n @if (showPrefRejectButton) {\n <button type=\"button\" class=\"tabs-pref-reject-button\">\n <span class=\"tabs-pref-reject-button__icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\">\n <g>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M10.9353 4.11938C11.1384 4.3225 11.1384 4.65183 10.9353 4.85495L2.35324 13.437C2.15012 13.6401 1.82079 13.6401 1.61767 13.437C1.41455 13.2339 1.41455 12.9046 1.61767 12.7014L10.1997 4.11938C10.4028 3.91626 10.7322 3.91626 10.9353 4.11938Z\" fill=\"#FE3C72\"/>\n <circle cx=\"6.14645\" cy=\"8.64816\" r=\"4.0\" stroke=\"#FE3C72\" stroke-width=\"1\"/>\n </g>\n </svg>\n </span>\n <span class=\"tabs-pref-reject-button__label\">Reject</span>\n </button>\n }\n\n <!-- Global menu overlay -->\n @if (showGlobalMenu) {\n <div class=\"global-menu-overlay\" (click)=\"toggleGlobalMenu($event)\"></div>\n }\n\n <!-- Context menu overlay -->\n @if (activeContextMenuNode) {\n <div class=\"context-menu-overlay\" (click)=\"closeMenus()\"></div>\n }\n\n <!-- \u2500\u2500 Context menu (portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #contextMenuTemplate>\n @if (activeContextMenuNode) {\n <div class=\"context-menu\"\n [style.left.px]=\"contextMenuPosition.x\"\n [style.top.px]=\"contextMenuPosition.y\"\n style=\"position: fixed; z-index: 100000;\">\n @if (activeContextMenuNode?.type === 'group' || activeContextMenuNode?.type === 'item') {\n <div class=\"menu-item\" (click)=\"toggleRepositionMode()\">\n {{ repositionMode && (!repositionTargetId || repositionTargetId === getSafeId(activeContextMenuNode?.data)) ? 'End Reposition' : 'Reposition' }}\n </div>\n }\n @if (activeContextMenuNode?.type === 'group') {\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"handleMenuAction('ungroup', activeContextMenuNode!)\">Ungroup</div>\n }\n </div>\n }\n </ng-template>\n\n <!-- \u2500\u2500 Confirmation dialog (Popper) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <lib-popper-content #confirmPopper>\n <div class=\"popover-container\">\n <div class=\"m-title f-w-700 f-lg h-160 f-white\">Overwrite Manual Groups?</div>\n <span class=\"message f-w-400 f-md h-150 f-gray\">\n This operation will discard your current manual arrangement.\n Continue?\n </span>\n <div class=\"buttons\">\n <lib-secondary-btn (click)=\"cancelGroupBy()\" type=\"button\">Cancel</lib-secondary-btn>\n <lib-primary-btn (click)=\"confirmGroupBy()\" type=\"button\">Continue</lib-primary-btn>\n </div>\n </div>\n </lib-popper-content>\n\n <!-- \u2500\u2500 Alert / Toastr (portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #alertTemplate>\n <div class=\"tabs-alert-host\">\n <lib-alert-popup\n [title]=\"alertTitle\"\n [description]=\"alertDescription\"\n [timeState]=\"alertTimeState\"\n (closed)=\"dismissAlert()\">\n </lib-alert-popup>\n </div>\n </ng-template>\n\n <!-- Main Content Swiper -->\n <div class=\"swiper-container main-swiper\" [style.max-height]=\"slideContentMaxHeight\" [ngStyle]=\"{ height: mainSwiperHeight }\">\n <swiper-container #mainSwiper init=\"false\" class=\"main-swiper\"\n [class.container-sides-shadow]=\"activeIndex !== 0\"\n [ngStyle]=\"{ height: subMainSwiperHeight }\">\n @for (item of displayItems; track trackByItem($index, item)) {\n <swiper-slide>\n <ng-container *ngTemplateOutlet=\"contentTemplate; context: { $implicit: item, index: $index }\"></ng-container>\n </swiper-slide>\n }\n </swiper-container>\n </div>\n\n </ng-container>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;min-width:0;height:100%;display:flex;flex-direction:column;padding-top:0;font-family:Gilroy,sans-serif}.swipeable-tabs-container{position:relative;display:flex;width:100%;height:100%;min-height:0;flex-direction:column;flex:1}.swipeable-tabs-container.bottom-thumbs{flex-direction:column-reverse}.swipeable-tabs-container>.main-swiper{flex:1;display:flex;flex-direction:column;z-index:100}.swipeable-tabs-container swiper-container{position:relative;display:block;overflow:auto;width:100%;height:100%}.swipeable-tabs-container swiper-container{scrollbar-width:none}.swipeable-tabs-container swiper-container::-webkit-scrollbar{display:none}.expanded-item-portal{position:fixed;transform:translate(-50%,-50%);z-index:1000;pointer-events:auto}.settings-trigger-wrapper{position:absolute;top:-15px;right:0;z-index:3000;pointer-events:none}.settings-trigger-wrapper.settings-trigger-wrapper-portal{position:fixed;top:0;right:auto;z-index:3000;pointer-events:none}.settings-trigger{padding:8px;cursor:pointer;color:#fffc;transition:all .3s ease;pointer-events:auto;display:flex;align-items:center;justify-content:center;background:transparent;background:radial-gradient(circle,rgba(0,0,0,.9) 0%,transparent 70%);box-shadow:none;border:none;border-radius:50%}.settings-trigger:hover{color:#fff;background:radial-gradient(circle,rgba(0,0,0,.95) 0%,transparent 70%)}.settings-trigger i{font-size:1.5rem;filter:drop-shadow(0px 0px 2px rgba(0,0,0,.8))}.settings-trigger.settings-trigger--hidden{visibility:hidden;pointer-events:none}.global-menu-overlay,.context-menu-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2000;background:transparent}.global-menu{position:absolute;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border:none;border-radius:13px;padding:5px 0;min-width:150px;z-index:3001;display:flex;flex-direction:column;overflow:hidden;right:0;left:auto;pointer-events:auto}.popover-container{pointer-events:auto;z-index:5000}.menu-up{top:auto;bottom:100%;margin-bottom:10px;margin-top:0;transform-origin:bottom right;animation:fadeIn .2s ease-out}.menu-down{top:100%;bottom:auto;margin-top:10px;margin-bottom:0;transform-origin:top right;animation:fadeInDown .2s ease-out}.context-menu{position:fixed;margin-left:-17px;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border:none;border-radius:13px;padding:5px 0;min-width:150px;z-index:1002;display:flex;flex-direction:column;overflow:hidden}.context-menu{animation:scaleIn .15s ease-out}.menu-item{padding:12px 20px;color:#ffffffe6;font-family:Gilroy,sans-serif;font-weight:700;font-size:11px;line-height:100%;letter-spacing:.07px;vertical-align:middle;cursor:pointer;transition:background .2s;white-space:nowrap;display:flex;align-items:center}.menu-item:hover{background:#ffffff1a}.global-menu .menu-item{justify-content:flex-end;text-align:right;padding-right:20px}.context-menu .menu-item{justify-content:flex-start;text-align:left;padding-left:20px}.menu-separator{height:1px;background:linear-gradient(to right,transparent,rgba(255,255,255,.3),transparent);margin:8px auto;width:50%}.global-menu .menu-separator{margin-left:auto;margin-right:10%}.context-menu .menu-separator{margin-right:auto;margin-left:10%}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes scaleIn{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}.item-ellipsis{cursor:pointer;color:#ffffff80;padding:2px;border-radius:50%;transition:all .2s}.item-ellipsis:hover{color:#fff;background:#ffffff1a}.item-ellipsis i{font-size:.9rem}.tab-item{width:54px;min-width:27px;height:54px;display:flex;align-items:center;justify-content:center;line-height:0}.tab-item img,.tab-item .avatar{width:auto;height:auto;object-fit:cover;border-radius:50%;margin:0}.tab-item.is-expanded-source{visibility:hidden;min-width:174px!important;flex-shrink:0}.tab-item.expanded-item{height:auto!important;width:auto!important}.tab-item.ungrouped{position:relative}.tab-item.ungrouped .item-ellipsis{position:absolute;bottom:0;right:0;z-index:10;background:#00000080}.tab-bar-container{display:flex;flex-direction:row;overflow-x:auto;overflow-y:hidden;width:100%;max-width:100%;min-width:0;flex-shrink:0;position:relative;z-index:1000;pointer-events:auto;-ms-overflow-style:none;scrollbar-width:none}.tab-bar-container:focus{outline:none}.tab-bar-container.grab-cursor{cursor:grab}.tab-bar-container.grabbing-cursor{cursor:grabbing;-webkit-user-select:none;user-select:none}.tab-bar-container::-webkit-scrollbar{display:none}.tab-bar-container.grouping-animating .cdk-drag-animating{transition:none!important}.tab-bar-container.grouping-animating .tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder){transition:none!important}.tab-bar-container.grouping-animating .cdk-drag-preview{display:none!important}.tabs-pref-reject-button{position:absolute;left:30%;transform:translate(-50%);bottom:calc(var(--thumbs-height, 40px) + 5px);display:inline-flex;align-items:center;gap:6px;padding:0 10px;height:29px;border:none;border-radius:8px;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 2px 4px #00000040,0 4px 4px #00000040,2px -2px 3px #0006 inset,0 -2px 8px #fff3 inset;color:#d9d9d9;font-family:Gilroy,sans-serif;font-size:8px;letter-spacing:.07px;cursor:pointer;z-index:1100}.tabs-pref-reject-button__icon{display:flex;align-items:center;justify-content:center}.tabs-pref-reject-button__label{line-height:1}.tab-list-root{display:flex;flex-direction:row;align-items:center;gap:10px;padding:0 100px 0 20px;min-width:100%;width:max-content;flex-shrink:0;flex-grow:1;height:100%}.tab-list-root .cdk-drag-placeholder{width:2px!important;min-width:2px!important;height:40px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;flex:0 0 auto;visibility:visible!important}.tab-node-wrapper{display:flex;align-items:center;flex-shrink:0;pointer-events:auto;position:relative;z-index:2;width:auto;min-width:min-content}.cdk-drag-preview{box-sizing:border-box;border-radius:0;box-shadow:none;z-index:9999!important;opacity:.5;width:auto;height:auto;display:inline-flex;align-items:center;justify-content:center;overflow:visible;pointer-events:none;scrollbar-width:none}.cdk-drag-preview::-webkit-scrollbar{display:none}.recently-dropped{opacity:.5;animation:fadeBackIn 1s ease-in forwards;animation-delay:2s}@keyframes fadeBackIn{0%{opacity:.5}to{opacity:1}}.cdk-drag-placeholder{opacity:0}.hidden-placeholder~.cdk-drag-preview,.tab-node-wrapper:has(.hidden-placeholder){transition:none!important}.tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.group-container{border:none;position:relative;display:flex;flex-direction:row;align-items:flex-start;padding:0 0 0 4px;box-sizing:border-box;isolation:isolate;margin-right:20px;background:transparent;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 8px 32px #0000005e,inset 0 1px #ffffff4d;border-radius:9px;overflow:visible;transition:all .3s ease}.group-container.pulsating-group{animation:pulsate-group-border 1.5s infinite}.group-container:before{content:\"\";position:absolute;inset:0 auto 0 0;width:min(45px,50%);background:linear-gradient(to right,var(--group-accent-color, rgba(255, 255, 255, .1)),transparent);opacity:.6;filter:blur(15px);z-index:0;pointer-events:none;border-radius:inherit;clip-path:inset(0 0 0 0 round 9px)}.group-container:not(:has(.tab-item.is-expanded-source)){overflow:hidden}.group-container:has(.tab-item.is-expanded-source){overflow:visible;z-index:50}.group-container:has(.tab-item.is-expanded-source):before{clip-path:inset(0 0 0 0 round 9px);overflow:hidden}.group-container.collapsed{width:auto;max-width:none;padding-left:2px}.group-container.collapsed .group-list,.group-container.collapsed .group-ellipsis-vertical{display:none}.group-container.collapsed:before{width:min(32px,30%)}.group-container:has(.tab-item.expanded-item){overflow:visible;z-index:50}@keyframes pulsate-group-border{0%{box-shadow:0 0 #ffffffb3,0 8px 32px #0000005e,inset 0 1px #ffffff4d}70%{box-shadow:0 0 0 6px #fff0,0 8px 32px #0000005e,inset 0 1px #ffffff4d}to{box-shadow:0 0 #fff0,0 8px 32px #0000005e,inset 0 1px #ffffff4d}}.group-title-text{font-family:Calistoga,serif;font-weight:400;font-style:normal;font-size:10px;line-height:100%;letter-spacing:0%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff6;max-height:40px;text-align:center;width:100%;display:block;margin-top:6px}.group-header-vertical{width:30px;align-self:stretch;display:flex;flex-direction:column;padding:0 2px;cursor:grab;z-index:20;position:relative;height:54px;max-height:54px;background:transparent}.group-header-vertical:before{content:\"\";position:absolute;inset:0;background:linear-gradient(to right,var(--group-accent-color, rgba(255, 255, 255, .1)),transparent);opacity:.5;filter:blur(4px);z-index:-1}.group-header-vertical>*{position:relative;z-index:1}.group-container.collapsed{border-radius:13px}.group-container.collapsed .group-header-vertical{justify-content:center;align-items:center;width:18px}.group-container.collapsed .group-title-text{margin-bottom:5px;text-align:center}.group-container:not(.collapsed) .group-header-vertical{justify-content:space-around;align-items:flex-start;padding-left:0;padding-bottom:0;padding-top:0}.group-title-vertical{display:flex;align-items:center;justify-content:center;writing-mode:vertical-rl;transform:rotate(180deg);padding:0;margin-bottom:0;overflow:hidden;min-height:40px}.group-ellipsis-vertical{cursor:pointer;align-items:center;justify-content:space-between;width:100%;height:auto;position:static;margin:-11px 0 0;padding-left:0;display:flex;justify-content:flex-start;gap:3px;padding-bottom:5px}.group-ellipsis-vertical:hover{opacity:.7}.group-ellipsis-vertical .group-ellipsis-dot{width:3px;height:3px;background-color:#fff;border-radius:50%!important;display:block}.tab-bar-container.dragging-active .group-header-vertical{z-index:1;pointer-events:none}.group-list{padding-top:2px;display:flex;align-items:center;justify-content:space-around;min-width:40px;margin-left:-13.5px;margin-right:-11.5px;margin-top:-7.5px;gap:20px;border-radius:4px;position:relative;z-index:1;pointer-events:auto}.group-list .tab-item.is-expanded-source,.group-list .tab-item.is-expanded-source.cdk-drag-placeholder{min-width:174px!important;visibility:visible!important;opacity:.5}.group-list.collapsed-drop-target{position:absolute;top:0;left:0;width:100%;height:100%;min-width:unset;background:#ffffff4d;border:2px dashed rgba(255,255,255,.8);z-index:50;border-radius:16px}.group-list.collapsed-drop-target .tab-item{display:none}.reposition-placeholder{width:2px!important;min-width:2px!important;height:40px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;border:none;box-shadow:none;flex:0 0 auto}.group-list .cdk-drag-placeholder{width:2px!important;min-width:2px!important;height:46px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;border:none;box-shadow:0 0 6px 2px #fe3c7299!important;flex:0 0 auto;visibility:visible!important}.hidden-placeholder{visibility:hidden!important;pointer-events:none!important}.tab-node-wrapper.potential-group-target .tab-item.ungrouped{display:none}.visual-group-wrapper{border:none;display:flex;flex-direction:row;align-items:flex-start;padding:3px 3px 3px 4px;background:transparent;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 8px 32px #0000005e,inset 0 1px #ffffff4d;border-radius:9px;overflow:hidden;border:1px solid rgba(255,255,255,.2)}.visual-group-wrapper .group-header-vertical{width:18px;height:54px;background:#ffffff1a}.visual-group-wrapper .group-list-visual{display:flex;align-items:center;justify-content:space-around;gap:4.5px;margin-left:-4px;padding-top:2px}.visual-group-wrapper .ghost-item{opacity:.3;filter:grayscale(100%)}.grabbing-cursor{cursor:grabbing!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder),.group-list.cdk-drop-list-dragging .tab-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.05)}to{transform:scale(1)}}.tabs-confirm-backdrop{position:fixed;inset:0;z-index:200000;background:#0000008c;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center}.tabs-confirm-dialog{background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 0 -6px 12px #403d4680;border-radius:16px;padding:24px 28px 20px;max-width:340px;width:calc(100vw - 48px);display:flex;flex-direction:column;gap:12px}.tabs-confirm-dialog__title{font-family:Calistoga,serif;font-size:14px;font-weight:400;color:#fff;line-height:1.3}.tabs-confirm-dialog__description{font-family:Gilroy,sans-serif;font-size:11px;font-weight:500;color:#ffffffb3;line-height:1.5}.tabs-confirm-dialog__actions{display:flex;justify-content:flex-end;gap:10px;margin-top:4px}.tabs-confirm-btn{font-family:Gilroy,sans-serif;font-weight:700;font-size:11px;letter-spacing:.07px;border:none;border-radius:8px;padding:8px 18px;cursor:pointer;transition:opacity .2s}.tabs-confirm-btn:hover{opacity:.85}.tabs-confirm-btn--cancel{background:#ffffff1a;color:#ffffffbf}.tabs-confirm-btn--confirm{background:#fe3c72;color:#fff}.tabs-alert-host{position:fixed;top:20px;right:20px;z-index:300000;pointer-events:auto}\n"] }]
|
|
6867
|
+
args: [{ selector: 'lib-dashboard-swipeable-tabs', imports: [CommonModule, TranslateModule, DragDropModule, CdkScrollable, AlertPopupComponent, ButtonsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"swipeable-tabs-container\"\n [class.bottom-thumbs]=\"bottomThumbs\"\n [ngStyle]=\"{ height: generalSwiperHeight }\"\n [style.--thumbs-height]=\"thumbsSwiperHeight\"\n>\n\n <!-- \u2500\u2500 LEGACY MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (!enableGrouping) {\n <ng-container>\n <swiper-container #thumbSwiper init=\"false\" class=\"thumb-swiper container-sides-shadow\" [ngStyle]=\"{ height: thumbsSwiperHeight }\">\n <ng-content select=\"[thumb-slides]\"></ng-content>\n </swiper-container>\n <div class=\"swiper-container main-swiper\" [style.max-height]=\"slideContentMaxHeight\" [ngStyle]=\"{ height: mainSwiperHeight }\">\n <swiper-container #mainSwiper init=\"false\" class=\"main-swiper\" [class.container-sides-shadow]=\"activeIndex !== 0\" [ngStyle]=\"{ height: subMainSwiperHeight }\">\n <ng-content select=\"[main-slides]\"></ng-content>\n </swiper-container>\n </div>\n </ng-container>\n }\n\n <!-- \u2500\u2500 GROUPING MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (enableGrouping) {\n <ng-container>\n\n <!-- Settings trigger -->\n <div class=\"settings-trigger-wrapper\" #settingsTriggerWrapperEl>\n <div class=\"settings-trigger\" [class.settings-trigger--hidden]=\"settingsTriggerPortaled\" (click)=\"toggleGlobalMenu($event)\">\n <i class=\"pi pi-cog\"></i>\n </div>\n @if (showGlobalMenu) {\n <div class=\"global-menu\" [ngClass]=\"'menu-' + menuPosition\" (click)=\"$event.stopPropagation()\">\n <div class=\"menu-item\" (click)=\"requestGroupBy('response')\">Group by Response</div>\n <div class=\"menu-item\" (click)=\"requestGroupBy('client')\">Group by Client</div>\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"restoreCustomGroups()\">Restore Custom Groups</div>\n <div class=\"menu-item\" (click)=\"storeCustomGroups()\">Store Custom Groups</div>\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"ungroupAll()\">Ungroup All</div>\n </div>\n }\n </div>\n\n <ng-template #settingsTriggerPortalTemplate>\n <div\n class=\"settings-trigger-wrapper settings-trigger-wrapper-portal\"\n [style.left.px]=\"settingsTriggerPortalLeft\"\n [style.top.px]=\"settingsTriggerPortalTop\"\n >\n <div class=\"settings-trigger\" (click)=\"toggleGlobalMenu($event)\">\n <i class=\"pi pi-cog\"></i>\n </div>\n </div>\n </ng-template>\n\n <!-- Tab Bar -->\n <div class=\"tab-bar-container\"\n #tabBarContainer\n cdkScrollable\n [class.dragging-active]=\"isDragging\"\n [class.grouping-animating]=\"groupingAnimating\"\n [class.grab-cursor]=\"!repositionMode && !isScrollDragging\"\n [class.grabbing-cursor]=\"isScrollDragging\"\n [ngStyle]=\"{ minHeight: thumbsSwiperHeight }\"\n tabindex=\"0\">\n\n <div\n cdkDropList\n [id]=\"rootDropListId\"\n [cdkDropListConnectedTo]=\"connectedDropLists\"\n [cdkDropListEnterPredicate]=\"canDropToRoot\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"tabNodes\"\n (cdkDropListDropped)=\"drop($event)\"\n class=\"tab-list-root\">\n\n @for (node of tabNodes; track trackByNode($index, node); let i = $index) {\n <div cdkDrag\n [cdkDragData]=\"node\"\n [cdkDragDisabled]=\"!enableDragAndDrop || isRootNodeDragDisabled(node)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"dragEnded($event)\"\n class=\"tab-node-wrapper\"\n [class.potential-group-target]=\"isItem(node) && potentialGroupTargetId === getSafeId(node.data)\"\n [attr.data-id]=\"isItem(node) ? getSafeId(node.data) : null\"\n (mousedown)=\"onNodeDown($event)\"\n (touchstart)=\"onNodeDown($event)\"\n (mouseup)=\"onNodeMouseUp()\"\n (touchend)=\"onNodeMouseUp()\">\n\n <div *cdkDragPreview>\n <ng-container *ngTemplateOutlet=\"nodePreviewTemplate; context: { node: node }\"></ng-container>\n </div>\n <div *cdkDragPlaceholder [class.reposition-placeholder]=\"repositionMode\"></div>\n\n <!-- \u2500\u2500 Case 1: Ungrouped Item \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (isItem(node)) {\n <ng-container>\n <div class=\"tab-item ungrouped\"\n [class.is-expanded-source]=\"expandedItemId === getSafeId(node.data)\"\n [attr.data-expanded-id]=\"expandedItemId === getSafeId(node.data) ? expandedItemId : null\"\n [class.active]=\"displayItems.indexOf(node.data) === activeIndex\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(node.data)\"\n (click)=\"onItemClick($event, node)\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: false, expanded: false }\"></ng-container>\n </div>\n\n @if (potentialGroupTargetId === getSafeId(node.data)) {\n <div class=\"visual-group-wrapper\">\n <div class=\"group-header-vertical\"></div>\n <div class=\"group-list-visual\">\n <div class=\"tab-item\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: true, expanded: false }\"></ng-container>\n </div>\n <div class=\"tab-item ghost-item\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: draggedItemData?.data, grouped: true, expanded: false }\"></ng-container>\n </div>\n </div>\n </div>\n }\n </ng-container>\n }\n\n <!-- \u2500\u2500 Case 2: Group Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (isGroup(node)) {\n <ng-container>\n <div class=\"group-container\"\n [class.collapsed]=\"node.data.collapsed\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(node.data)\"\n [class.pulsating-group]=\"repositionMode && repositionTargetId === getSafeId(node.data)\"\n [style.border-color]=\"node.data.color\"\n [style.--group-accent-color]=\"node.data.color\"\n cdkDragHandle\n [cdkDragHandleDisabled]=\"!enableDragAndDrop || isRootNodeDragDisabled(node) || repositionTargetGroupId === node.id\"\n (mousedown)=\"onNodeDown($event)\"\n (touchstart)=\"onNodeDown($event)\"\n (mouseup)=\"onNodeMouseUp()\"\n (touchend)=\"onNodeMouseUp()\">\n\n <div class=\"group-header-vertical\" (click)=\"toggleGroup(node.data)\">\n <div class=\"group-title-vertical\">\n <span class=\"group-title-text\">{{ getTruncatedTitle(node.data.title, node.data.collapsed) }}</span>\n </div>\n <div class=\"group-ellipsis-vertical\"\n (click)=\"openContextMenu($event, node); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n (touchstart)=\"$event.stopPropagation()\">\n <div class=\"group-ellipsis-dot\"></div>\n <div class=\"group-ellipsis-dot\"></div>\n <div class=\"group-ellipsis-dot\"></div>\n </div>\n </div>\n\n <div cdkDropList\n [id]=\"'group-list-' + getSafeId(node.data)\"\n [cdkDropListConnectedTo]=\"connectedDropLists\"\n [cdkDropListData]=\"node.data.items\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListEnterPredicate]=\"canDropToGroup\"\n cdkDropListOrientation=\"horizontal\"\n class=\"group-list\"\n [class.collapsed-drop-target]=\"node.data.collapsed && isDragging\">\n\n @for (item of node.data.items; track trackByItem($index, item)) {\n <div class=\"tab-item\"\n cdkDrag\n [class.is-expanded-source]=\"expandedItemId === getSafeId(item)\"\n [attr.data-expanded-id]=\"expandedItemId === getSafeId(item) ? expandedItemId : null\"\n [cdkDragData]=\"{ type: 'item', data: item }\"\n [cdkDragDisabled]=\"!enableDragAndDrop || isItemDragDisabled(getSafeId(item), node.id)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"dragEnded($event)\"\n [class.active]=\"displayItems.indexOf(item) === activeIndex\"\n [class.recently-dropped]=\"recentlyDroppedId === getSafeId(item)\"\n (click)=\"onItemClick($event, { type: 'item', data: item, id: getSafeId(item) })\">\n\n <div *cdkDragPreview>\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item, grouped: true, expanded: false }\"></ng-container>\n </div>\n <div *cdkDragPlaceholder [class.reposition-placeholder]=\"repositionMode\"></div>\n\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item, grouped: true, expanded: false }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </ng-container>\n }\n </div>\n }\n\n <!-- Drag preview template -->\n <ng-template #nodePreviewTemplate let-node=\"node\">\n @if (isItem(node)) {\n <div class=\"tab-item ungrouped\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: node.data, grouped: false, expanded: false }\"></ng-container>\n </div>\n }\n @if (isGroup(node)) {\n <div class=\"group-container collapsed\"\n [style.border-color]=\"node.data.color\"\n [style.--group-accent-color]=\"node.data.color\">\n <div class=\"group-header-vertical\">\n <div class=\"group-title-vertical\">\n <span class=\"group-title-text\">{{ getTruncatedTitle(node.data.title, true) }}</span>\n </div>\n </div>\n </div>\n }\n </ng-template>\n\n </div>\n </div>\n\n <ng-template #expandedPortalTemplate>\n @if (expandedItemId && portalRect && !(isDragging && getSafeId(draggedItemData?.data) === expandedItemId)) {\n <div class=\"expanded-item-portal\"\n [attr.data-expanded-portal-id]=\"expandedItemId\"\n [style.left.px]=\"portalRect.left\"\n [style.top.px]=\"portalRect.top\"\n [style.width.px]=\"portalRect.width\"\n (pointerdown)=\"onScrollPointerDown($event)\"\n (mousedown)=\"onPortalDown($event)\"\n (touchstart)=\"onPortalDown($event)\"\n (click)=\"onPortalClick($event)\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: expandedItemRef, grouped: false, expanded: true }\"></ng-container>\n </div>\n }\n </ng-template>\n\n @if (showPrefRejectButton) {\n <button type=\"button\" class=\"tabs-pref-reject-button\">\n <span class=\"tabs-pref-reject-button__icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\">\n <g>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M10.9353 4.11938C11.1384 4.3225 11.1384 4.65183 10.9353 4.85495L2.35324 13.437C2.15012 13.6401 1.82079 13.6401 1.61767 13.437C1.41455 13.2339 1.41455 12.9046 1.61767 12.7014L10.1997 4.11938C10.4028 3.91626 10.7322 3.91626 10.9353 4.11938Z\" fill=\"#FE3C72\"/>\n <circle cx=\"6.14645\" cy=\"8.64816\" r=\"4.0\" stroke=\"#FE3C72\" stroke-width=\"1\"/>\n </g>\n </svg>\n </span>\n <span class=\"tabs-pref-reject-button__label\">Reject</span>\n </button>\n }\n\n <!-- Global menu overlay -->\n @if (showGlobalMenu) {\n <div class=\"global-menu-overlay\" (click)=\"toggleGlobalMenu($event)\"></div>\n }\n\n <!-- Context menu overlay -->\n @if (activeContextMenuNode) {\n <div class=\"context-menu-overlay\" (click)=\"closeMenus()\"></div>\n }\n\n <!-- \u2500\u2500 Context menu (portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #contextMenuTemplate>\n @if (activeContextMenuNode) {\n <div class=\"context-menu\"\n [style.left.px]=\"contextMenuPosition.x\"\n [style.top.px]=\"contextMenuPosition.y\"\n style=\"position: fixed; z-index: 100000;\">\n @if (activeContextMenuNode?.type === 'group' || activeContextMenuNode?.type === 'item') {\n <div class=\"menu-item\" (click)=\"toggleRepositionMode()\">\n {{ repositionMode && (!repositionTargetId || repositionTargetId === getSafeId(activeContextMenuNode?.data)) ? 'End Reposition' : 'Reposition' }}\n </div>\n }\n @if (activeContextMenuNode?.type === 'group') {\n <div class=\"menu-separator\"></div>\n <div class=\"menu-item\" (click)=\"handleMenuAction('ungroup', activeContextMenuNode!)\">Ungroup</div>\n }\n </div>\n }\n </ng-template>\n\n <!-- \u2500\u2500 Confirmation dialog (Portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #confirmDialogTemplate>\n <div class=\"confirm-dialog-overlay\" (click)=\"cancelGroupBy()\">\n <div class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"m-title f-w-700 f-lg h-160 f-white\">Overwrite Manual Groups?</div>\n <span class=\"message f-w-400 f-md h-150 f-gray\">\n This operation will discard your current manual arrangement.\n Continue?\n </span>\n <div class=\"buttons\">\n <lib-secondary-btn (click)=\"cancelGroupBy()\" type=\"button\">Cancel</lib-secondary-btn>\n <lib-primary-btn (click)=\"confirmGroupBy()\" type=\"button\">Continue</lib-primary-btn>\n </div>\n </div>\n </div>\n </ng-template>\n\n <!-- \u2500\u2500 Alert / Toastr (portal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #alertTemplate>\n <div class=\"tabs-alert-host\">\n <lib-alert-popup\n [title]=\"alertTitle\"\n [description]=\"alertDescription\"\n [timeState]=\"alertTimeState\"\n (closed)=\"dismissAlert()\">\n </lib-alert-popup>\n </div>\n </ng-template>\n\n <!-- Main Content Swiper -->\n <div class=\"swiper-container main-swiper\" [style.max-height]=\"slideContentMaxHeight\" [ngStyle]=\"{ height: mainSwiperHeight }\">\n <swiper-container #mainSwiper init=\"false\" class=\"main-swiper\"\n [class.container-sides-shadow]=\"activeIndex !== 0\"\n [ngStyle]=\"{ height: subMainSwiperHeight }\">\n @for (item of displayItems; track trackByItem($index, item)) {\n <swiper-slide>\n <ng-container *ngTemplateOutlet=\"contentTemplate; context: { $implicit: item, index: $index }\"></ng-container>\n </swiper-slide>\n }\n </swiper-container>\n </div>\n\n </ng-container>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;min-width:0;height:100%;display:flex;flex-direction:column;padding-top:0;font-family:Gilroy,sans-serif}.swipeable-tabs-container{position:relative;display:flex;width:100%;height:100%;min-height:0;flex-direction:column;flex:1}.swipeable-tabs-container.bottom-thumbs{flex-direction:column-reverse}.swipeable-tabs-container>.main-swiper{flex:1;display:flex;flex-direction:column;z-index:100}.swipeable-tabs-container swiper-container{position:relative;display:block;overflow:auto;width:100%;height:100%}.swipeable-tabs-container swiper-container{scrollbar-width:none}.swipeable-tabs-container swiper-container::-webkit-scrollbar{display:none}.expanded-item-portal{position:fixed;transform:translate(-50%,-50%);z-index:1000;pointer-events:auto}.settings-trigger-wrapper{position:absolute;top:-15px;right:0;z-index:3000;pointer-events:none}.settings-trigger-wrapper.settings-trigger-wrapper-portal{position:fixed;top:0;right:auto;z-index:3000;pointer-events:none}.settings-trigger{padding:8px;cursor:pointer;color:#fffc;transition:all .3s ease;pointer-events:auto;display:flex;align-items:center;justify-content:center;background:transparent;background:radial-gradient(circle,rgba(0,0,0,.9) 0%,transparent 70%);box-shadow:none;border:none;border-radius:50%}.settings-trigger:hover{color:#fff;background:radial-gradient(circle,rgba(0,0,0,.95) 0%,transparent 70%)}.settings-trigger i{font-size:1.5rem;filter:drop-shadow(0px 0px 2px rgba(0,0,0,.8))}.settings-trigger.settings-trigger--hidden{visibility:hidden;pointer-events:none}.global-menu-overlay,.context-menu-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2000;background:transparent}.confirm-dialog-overlay{position:fixed;inset:0;width:100vw;height:100vh;z-index:100000;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:24px;pointer-events:auto}.confirm-dialog{width:min(420px,100%);background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border-radius:13px;padding:16px;pointer-events:auto}.confirm-dialog .buttons{display:flex;justify-content:flex-end;gap:12px;margin-top:16px}.global-menu{position:absolute;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border:none;border-radius:13px;padding:5px 0;min-width:150px;z-index:3001;display:flex;flex-direction:column;overflow:hidden;right:0;left:auto;pointer-events:auto}.menu-up{top:auto;bottom:100%;margin-bottom:10px;margin-top:0;transform-origin:bottom right;animation:fadeIn .2s ease-out}.menu-down{top:100%;bottom:auto;margin-top:10px;margin-bottom:0;transform-origin:top right;animation:fadeInDown .2s ease-out}.context-menu{position:fixed;margin-left:-17px;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 3px 0 6px #c8c8d259,inset 0 -6px 12px #403d4680,inset 0 -3px 6px #403d46cc,inset 16px 0 10px -2px #3a3a44e6,inset 0 -16px 10px -2px #3a3a44e6;border:none;border-radius:13px;padding:5px 0;min-width:150px;z-index:1002;display:flex;flex-direction:column;overflow:hidden}.context-menu{animation:scaleIn .15s ease-out}.menu-item{padding:12px 20px;color:#ffffffe6;font-family:Gilroy,sans-serif;font-weight:700;font-size:11px;line-height:100%;letter-spacing:.07px;vertical-align:middle;cursor:pointer;transition:background .2s;white-space:nowrap;display:flex;align-items:center}.menu-item:hover{background:#ffffff1a}.global-menu .menu-item{justify-content:flex-end;text-align:right;padding-right:20px}.context-menu .menu-item{justify-content:flex-start;text-align:left;padding-left:20px}.menu-separator{height:1px;background:linear-gradient(to right,transparent,rgba(255,255,255,.3),transparent);margin:8px auto;width:50%}.global-menu .menu-separator{margin-left:auto;margin-right:10%}.context-menu .menu-separator{margin-right:auto;margin-left:10%}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes scaleIn{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}.item-ellipsis{cursor:pointer;color:#ffffff80;padding:2px;border-radius:50%;transition:all .2s}.item-ellipsis:hover{color:#fff;background:#ffffff1a}.item-ellipsis i{font-size:.9rem}.tab-item{width:54px;min-width:27px;height:54px;display:flex;align-items:center;justify-content:center;line-height:0}.tab-item img,.tab-item .avatar{width:auto;height:auto;object-fit:cover;border-radius:50%;margin:0}.tab-item.is-expanded-source{visibility:hidden;min-width:174px!important;flex-shrink:0}.tab-item.expanded-item{height:auto!important;width:auto!important}.tab-item.ungrouped{position:relative}.tab-item.ungrouped .item-ellipsis{position:absolute;bottom:0;right:0;z-index:10;background:#00000080}.tab-bar-container{display:flex;flex-direction:row;overflow-x:auto;overflow-y:hidden;width:100%;max-width:100%;min-width:0;flex-shrink:0;position:relative;z-index:1000;pointer-events:auto;-ms-overflow-style:none;scrollbar-width:none}.tab-bar-container:focus{outline:none}.tab-bar-container.grab-cursor{cursor:grab}.tab-bar-container.grabbing-cursor{cursor:grabbing;-webkit-user-select:none;user-select:none}.tab-bar-container::-webkit-scrollbar{display:none}.tab-bar-container.grouping-animating .cdk-drag-animating{transition:none!important}.tab-bar-container.grouping-animating .tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder){transition:none!important}.tab-bar-container.grouping-animating .cdk-drag-preview{display:none!important}.tabs-pref-reject-button{position:absolute;left:30%;transform:translate(-50%);bottom:calc(var(--thumbs-height, 40px) + 5px);display:inline-flex;align-items:center;gap:6px;padding:0 10px;height:29px;border:none;border-radius:8px;background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 2px 4px #00000040,0 4px 4px #00000040,2px -2px 3px #0006 inset,0 -2px 8px #fff3 inset;color:#d9d9d9;font-family:Gilroy,sans-serif;font-size:8px;letter-spacing:.07px;cursor:pointer;z-index:1100}.tabs-pref-reject-button__icon{display:flex;align-items:center;justify-content:center}.tabs-pref-reject-button__label{line-height:1}.tab-list-root{display:flex;flex-direction:row;align-items:center;gap:10px;padding:0 100px 0 20px;min-width:100%;width:max-content;flex-shrink:0;flex-grow:1;height:100%}.tab-list-root .cdk-drag-placeholder{width:2px!important;min-width:2px!important;height:40px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;flex:0 0 auto;visibility:visible!important}.tab-node-wrapper{display:flex;align-items:center;flex-shrink:0;pointer-events:auto;position:relative;z-index:2;width:auto;min-width:min-content}.cdk-drag-preview{box-sizing:border-box;border-radius:0;box-shadow:none;z-index:9999!important;opacity:.5;width:auto;height:auto;display:inline-flex;align-items:center;justify-content:center;overflow:visible;pointer-events:none;scrollbar-width:none}.cdk-drag-preview::-webkit-scrollbar{display:none}.recently-dropped{opacity:.5;animation:fadeBackIn 1s ease-in forwards;animation-delay:2s}@keyframes fadeBackIn{0%{opacity:.5}to{opacity:1}}.cdk-drag-placeholder{opacity:0}.hidden-placeholder~.cdk-drag-preview,.tab-node-wrapper:has(.hidden-placeholder){transition:none!important}.tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.group-container{border:none;position:relative;display:flex;flex-direction:row;align-items:flex-start;padding:0 0 0 4px;box-sizing:border-box;isolation:isolate;margin-right:20px;background:transparent;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 8px 32px #0000005e,inset 0 1px #ffffff4d;border-radius:9px;overflow:visible;transition:all .3s ease}.group-container.pulsating-group{animation:pulsate-group-border 1.5s infinite}.group-container:before{content:\"\";position:absolute;inset:0 auto 0 0;width:min(45px,50%);background:linear-gradient(to right,var(--group-accent-color, rgba(255, 255, 255, .1)),transparent);opacity:.6;filter:blur(15px);z-index:0;pointer-events:none;border-radius:inherit;clip-path:inset(0 0 0 0 round 9px)}.group-container:not(:has(.tab-item.is-expanded-source)){overflow:hidden}.group-container:has(.tab-item.is-expanded-source){overflow:visible;z-index:50}.group-container:has(.tab-item.is-expanded-source):before{clip-path:inset(0 0 0 0 round 9px);overflow:hidden}.group-container.collapsed{width:auto;max-width:none;padding-left:2px}.group-container.collapsed .group-list,.group-container.collapsed .group-ellipsis-vertical{display:none}.group-container.collapsed:before{width:min(32px,30%)}.group-container:has(.tab-item.expanded-item){overflow:visible;z-index:50}@keyframes pulsate-group-border{0%{box-shadow:0 0 #ffffffb3,0 8px 32px #0000005e,inset 0 1px #ffffff4d}70%{box-shadow:0 0 0 6px #fff0,0 8px 32px #0000005e,inset 0 1px #ffffff4d}to{box-shadow:0 0 #fff0,0 8px 32px #0000005e,inset 0 1px #ffffff4d}}.group-title-text{font-family:Calistoga,serif;font-weight:400;font-style:normal;font-size:10px;line-height:100%;letter-spacing:0%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff6;max-height:40px;text-align:center;width:100%;display:block;margin-top:6px}.group-header-vertical{width:30px;align-self:stretch;display:flex;flex-direction:column;padding:0 2px;cursor:grab;z-index:20;position:relative;height:54px;max-height:54px;background:transparent}.group-header-vertical:before{content:\"\";position:absolute;inset:0;background:linear-gradient(to right,var(--group-accent-color, rgba(255, 255, 255, .1)),transparent);opacity:.5;filter:blur(4px);z-index:-1}.group-header-vertical>*{position:relative;z-index:1}.group-container.collapsed{border-radius:13px}.group-container.collapsed .group-header-vertical{justify-content:center;align-items:center;width:18px}.group-container.collapsed .group-title-text{margin-bottom:5px;text-align:center}.group-container:not(.collapsed) .group-header-vertical{justify-content:space-around;align-items:flex-start;padding-left:0;padding-bottom:0;padding-top:0}.group-title-vertical{display:flex;align-items:center;justify-content:center;writing-mode:vertical-rl;transform:rotate(180deg);padding:0;margin-bottom:0;overflow:hidden;min-height:40px}.group-ellipsis-vertical{cursor:pointer;align-items:center;justify-content:space-between;width:100%;height:auto;position:static;margin:-11px 0 0;padding-left:0;display:flex;justify-content:flex-start;gap:3px;padding-bottom:5px}.group-ellipsis-vertical:hover{opacity:.7}.group-ellipsis-vertical .group-ellipsis-dot{width:3px;height:3px;background-color:#fff;border-radius:50%!important;display:block}.tab-bar-container.dragging-active .group-header-vertical{z-index:1;pointer-events:none}.group-list{padding-top:2px;display:flex;align-items:center;justify-content:space-around;min-width:40px;margin-left:-13.5px;margin-right:-11.5px;margin-top:-7.5px;gap:20px;border-radius:4px;position:relative;z-index:1;pointer-events:auto}.group-list .tab-item.is-expanded-source,.group-list .tab-item.is-expanded-source.cdk-drag-placeholder{min-width:174px!important;visibility:visible!important;opacity:.5}.group-list.collapsed-drop-target{position:absolute;top:0;left:0;width:100%;height:100%;min-width:unset;background:#ffffff4d;border:2px dashed rgba(255,255,255,.8);z-index:50;border-radius:16px}.group-list.collapsed-drop-target .tab-item{display:none}.reposition-placeholder{width:2px!important;min-width:2px!important;height:40px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;border:none;box-shadow:none;flex:0 0 auto}.group-list .cdk-drag-placeholder{width:2px!important;min-width:2px!important;height:46px!important;background-color:#fe3c72!important;margin:0 4px;opacity:1!important;border-radius:1px;border:none;box-shadow:0 0 6px 2px #fe3c7299!important;flex:0 0 auto;visibility:visible!important}.hidden-placeholder{visibility:hidden!important;pointer-events:none!important}.tab-node-wrapper.potential-group-target .tab-item.ungrouped{display:none}.visual-group-wrapper{border:none;display:flex;flex-direction:row;align-items:flex-start;padding:3px 3px 3px 4px;background:transparent;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);box-shadow:0 8px 32px #0000005e,inset 0 1px #ffffff4d;border-radius:9px;overflow:hidden;border:1px solid rgba(255,255,255,.2)}.visual-group-wrapper .group-header-vertical{width:18px;height:54px;background:#ffffff1a}.visual-group-wrapper .group-list-visual{display:flex;align-items:center;justify-content:space-around;gap:4.5px;margin-left:-4px;padding-top:2px}.visual-group-wrapper .ghost-item{opacity:.3;filter:grayscale(100%)}.grabbing-cursor{cursor:grabbing!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.tab-list-root.cdk-drop-list-dragging .tab-node-wrapper:not(.cdk-drag-placeholder),.group-list.cdk-drop-list-dragging .tab-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.05)}to{transform:scale(1)}}.tabs-confirm-backdrop{position:fixed;inset:0;z-index:200000;background:#0000008c;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center}.tabs-confirm-dialog{background:linear-gradient(180deg,#403d46,#3e3b44);box-shadow:0 8px 24px #00000080,0 2px 8px #0000004d,inset 6px 0 12px #c8c8d240,inset 0 -6px 12px #403d4680;border-radius:16px;padding:24px 28px 20px;max-width:340px;width:calc(100vw - 48px);display:flex;flex-direction:column;gap:12px}.tabs-confirm-dialog__title{font-family:Calistoga,serif;font-size:14px;font-weight:400;color:#fff;line-height:1.3}.tabs-confirm-dialog__description{font-family:Gilroy,sans-serif;font-size:11px;font-weight:500;color:#ffffffb3;line-height:1.5}.tabs-confirm-dialog__actions{display:flex;justify-content:flex-end;gap:10px;margin-top:4px}.tabs-confirm-btn{font-family:Gilroy,sans-serif;font-weight:700;font-size:11px;letter-spacing:.07px;border:none;border-radius:8px;padding:8px 18px;cursor:pointer;transition:opacity .2s}.tabs-confirm-btn:hover{opacity:.85}.tabs-confirm-btn--cancel{background:#ffffff1a;color:#ffffffbf}.tabs-confirm-btn--confirm{background:#fe3c72;color:#fff}.tabs-alert-host{position:fixed;top:20px;right:20px;z-index:300000;pointer-events:auto}\n"] }]
|
|
6802
6868
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i0.NgZone }], propDecorators: { thumbSwiper: [{
|
|
6803
6869
|
type: ViewChild,
|
|
6804
6870
|
args: ['thumbSwiper', { static: false }]
|
|
@@ -6861,9 +6927,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
6861
6927
|
}], contextMenuTemplate: [{
|
|
6862
6928
|
type: ViewChild,
|
|
6863
6929
|
args: ['contextMenuTemplate']
|
|
6864
|
-
}],
|
|
6930
|
+
}], confirmDialogTemplate: [{
|
|
6865
6931
|
type: ViewChild,
|
|
6866
|
-
args: ['
|
|
6932
|
+
args: ['confirmDialogTemplate']
|
|
6867
6933
|
}], alertTemplate: [{
|
|
6868
6934
|
type: ViewChild,
|
|
6869
6935
|
args: ['alertTemplate']
|