@sd-angular/core 19.0.0-beta.96 → 19.0.0-beta.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/document-builder/src/components/header-footer-builder/header-footer-builder.component.d.ts +2 -2
- package/components/document-builder/src/document-builder.model.d.ts +6 -2
- package/components/editor/src/editor.component.d.ts +8 -0
- package/components/editor/src/models/image-upload.plugin.model.d.ts +33 -0
- package/components/editor/src/plugins/image-upload/utils/style.utils.d.ts +1 -0
- package/components/table/index.d.ts +1 -0
- package/components/table/src/models/index.d.ts +1 -0
- package/components/table/src/models/table-item.model.d.ts +10 -0
- package/components/table/src/models/table-option-style.model.d.ts +6 -1
- package/components/table/src/models/table-option-tree.model.d.ts +12 -0
- package/components/table/src/models/table-option.model.d.ts +6 -0
- package/components/table/src/pipes/index.d.ts +1 -0
- package/components/table/src/pipes/sd-tree.pipe.d.ts +9 -0
- package/components/table/src/services/tree/tree.util.d.ts +14 -0
- package/components/table/src/table.component.d.ts +3 -0
- package/fesm2022/sd-angular-core-components-document-builder.mjs +9 -4
- package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-editor.mjs +222 -97
- package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tab-router.mjs +57 -15
- package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +325 -41
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-layout.mjs +172 -37
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/modules/layout/components/sidebar-v1/components/sidebar/sidebar.component.d.ts +8 -1
- package/modules/layout/configurations/layout.configuration.d.ts +8 -0
- package/modules/layout/services/storage/storage.service.d.ts +2 -0
- package/package.json +70 -70
- package/sd-angular-core-19.0.0-beta.97.tgz +0 -0
- package/sd-angular-core-19.0.0-beta.96.tgz +0 -0
|
@@ -57,6 +57,7 @@ class SdLayoutStorageService {
|
|
|
57
57
|
isShowSidebar;
|
|
58
58
|
menuLockStatus;
|
|
59
59
|
lastActiveMenuGroupId;
|
|
60
|
+
pinnedMenuGroup;
|
|
60
61
|
// End
|
|
61
62
|
constructor(sdStorageService) {
|
|
62
63
|
this.sdStorageService = sdStorageService;
|
|
@@ -64,6 +65,7 @@ class SdLayoutStorageService {
|
|
|
64
65
|
this.isShowSidebar = this.sdStorageService.create('cb07c316-ed6d-4620-9e92-53dbef6aa983');
|
|
65
66
|
this.menuLockStatus = this.sdStorageService.create('2c2f4816-18b3-4ec3-8177-7b90bff036c3');
|
|
66
67
|
this.lastActiveMenuGroupId = this.sdStorageService.create('2e6961d0-3380-4a94-a6a1-38837560cd96');
|
|
68
|
+
this.pinnedMenuGroup = this.sdStorageService.create('e81da122-5dab-4250-b309-64197fb19d44');
|
|
67
69
|
// End
|
|
68
70
|
}
|
|
69
71
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdLayoutStorageService, deps: [{ token: i1.SdStorageService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -405,29 +407,49 @@ class SidebarComponent {
|
|
|
405
407
|
titleMenuGroup = signal('');
|
|
406
408
|
idMenuGroupActive = signal('');
|
|
407
409
|
menusByGroup = signal([]);
|
|
410
|
+
#hoveredMenuNodeKey = signal(null);
|
|
411
|
+
#pinIconHoverTimerId = signal(null);
|
|
412
|
+
pinnedMenuGroup = signal(this.#layoutStorageService.pinnedMenuGroup.get() ?? {
|
|
413
|
+
id: 'pinned-menu-group',
|
|
414
|
+
title: 'Đã ghim',
|
|
415
|
+
children: [],
|
|
416
|
+
});
|
|
408
417
|
// ==========================================
|
|
409
418
|
// COMPUTED STATE
|
|
410
419
|
// ==========================================
|
|
411
420
|
totalMenuInMenusByGroup = computed(() => this.#getTotalMenus(this.menusByGroup()));
|
|
421
|
+
pinnedNodeKeys = computed(() => new Set(this.pinnedMenuGroup().children?.map(m => this.#getMenuNodeKey(m)) ?? []));
|
|
422
|
+
isPinnedMenuGroupActive = computed(() => this.idMenuGroupActive() === this.pinnedMenuGroup().id);
|
|
412
423
|
// ==========================================
|
|
413
424
|
// DATA STRUCTURES
|
|
414
425
|
// ==========================================
|
|
426
|
+
#pinIconHoverTimerDelay = 300;
|
|
427
|
+
#isFirstBindingMenu = signal(true);
|
|
415
428
|
dataSource = new MatTreeNestedDataSource();
|
|
416
429
|
treeControl = new NestedTreeControl(node => ('children' in node && node.children?.length ? node.children : []));
|
|
417
430
|
constructor() {
|
|
418
|
-
|
|
431
|
+
this.#setupEffects();
|
|
432
|
+
this.#setupSubscriptions();
|
|
433
|
+
}
|
|
434
|
+
#setupEffects() {
|
|
419
435
|
effect(() => {
|
|
420
436
|
const currentMenus = this.menus();
|
|
421
437
|
untracked(() => {
|
|
422
438
|
const lastActiveMenuGroupId = this.#layoutStorageService.lastActiveMenuGroupId.get();
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
439
|
+
const pinnedGroup = this.pinnedMenuGroup();
|
|
440
|
+
const isPinEnabled = this.sidebar()?.pin?.enabled;
|
|
441
|
+
// Xử lý khi lần đầu vào web (nếu chưa có active group)
|
|
442
|
+
if (!lastActiveMenuGroupId || (lastActiveMenuGroupId === pinnedGroup?.id && !isPinEnabled)) {
|
|
443
|
+
// Ưu tiên pinnedGroup nếu đủ điều kiện, còn không lấy menu đầu tiền dev khai báo
|
|
444
|
+
const targetId = isPinEnabled && pinnedGroup?.children?.length ? pinnedGroup?.id : currentMenus?.[0]?.id;
|
|
445
|
+
this.#layoutStorageService.lastActiveMenuGroupId.set(targetId ?? '');
|
|
426
446
|
}
|
|
427
447
|
this.#bindingMenuGroupByCurrentPath(currentMenus);
|
|
448
|
+
this.#isFirstBindingMenu.set(false);
|
|
428
449
|
});
|
|
429
450
|
});
|
|
430
|
-
|
|
451
|
+
}
|
|
452
|
+
#setupSubscriptions() {
|
|
431
453
|
this.#router.events.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe(event => {
|
|
432
454
|
if (event instanceof NavigationEnd) {
|
|
433
455
|
if (this.currentPath() !== window.location.pathname) {
|
|
@@ -444,6 +466,29 @@ class SidebarComponent {
|
|
|
444
466
|
onToggleMenuNode = (menu) => {
|
|
445
467
|
this.treeControl.toggle(menu);
|
|
446
468
|
};
|
|
469
|
+
isPinnedNode = (node) => this.pinnedNodeKeys().has(this.#getMenuNodeKey(node));
|
|
470
|
+
isHoveredNode = (node) => this.#hoveredMenuNodeKey() === this.#getMenuNodeKey(node);
|
|
471
|
+
expandPinnedGroup = () => {
|
|
472
|
+
const group = this.pinnedMenuGroup();
|
|
473
|
+
this.idMenuGroupActive.set(group.id);
|
|
474
|
+
this.#layoutStorageService.lastActiveMenuGroupId.set(group.id || '');
|
|
475
|
+
this.titleMenuGroup.set(group.title);
|
|
476
|
+
this.#setMenusByGroup(group.children ?? []);
|
|
477
|
+
this.searchText.set('');
|
|
478
|
+
this.expandSideBar.emit();
|
|
479
|
+
};
|
|
480
|
+
onTogglePin = (event, node) => {
|
|
481
|
+
event.stopPropagation();
|
|
482
|
+
const key = this.#getMenuNodeKey(node);
|
|
483
|
+
this.pinnedMenuGroup.update(group => {
|
|
484
|
+
const children = group.children ?? [];
|
|
485
|
+
const exists = children.some(m => this.#getMenuNodeKey(m) === key);
|
|
486
|
+
const updatedChildren = exists ? children.filter(m => this.#getMenuNodeKey(m) !== key) : [...children, node];
|
|
487
|
+
const updatedGroup = { id: 'pinned-menu-group', title: 'Đã ghim', children: updatedChildren };
|
|
488
|
+
this.#layoutStorageService.pinnedMenuGroup.set(updatedGroup);
|
|
489
|
+
return updatedGroup;
|
|
490
|
+
});
|
|
491
|
+
};
|
|
447
492
|
#onExpandAllMenuNodes = (menus) => {
|
|
448
493
|
menus?.forEach(menu => {
|
|
449
494
|
this.treeControl.expand(menu);
|
|
@@ -511,8 +556,7 @@ class SidebarComponent {
|
|
|
511
556
|
}
|
|
512
557
|
// Case 2: Menu có children
|
|
513
558
|
if ('children' in menuGroupNode && menuGroupNode.children?.length) {
|
|
514
|
-
this
|
|
515
|
-
this.dataSource.data = this.menusByGroup();
|
|
559
|
+
this.#setMenusByGroup(menuGroupNode.children);
|
|
516
560
|
this.searchText.set('');
|
|
517
561
|
this.onFilterSearchText('');
|
|
518
562
|
this.expandSideBar.emit();
|
|
@@ -557,8 +601,26 @@ class SidebarComponent {
|
|
|
557
601
|
}
|
|
558
602
|
};
|
|
559
603
|
onMouseOverMenuNode = (event, menuItem) => {
|
|
604
|
+
const menuNode = event.currentTarget;
|
|
605
|
+
const brandColor = this.sidebar()?.brandColor || '#2962FF';
|
|
606
|
+
// Nếu có bật config pin menu
|
|
607
|
+
if (this.sidebar()?.pin?.enabled) {
|
|
608
|
+
const iconPin = menuNode.querySelector('.c-menu-node-description-icon-pin');
|
|
609
|
+
if (iconPin) {
|
|
610
|
+
if (this.#pinIconHoverTimerId()) {
|
|
611
|
+
clearTimeout(this.#pinIconHoverTimerId());
|
|
612
|
+
this.#pinIconHoverTimerId.set(null);
|
|
613
|
+
}
|
|
614
|
+
this.#pinIconHoverTimerId.set(setTimeout(() => {
|
|
615
|
+
this.#hoveredMenuNodeKey.set(this.#getMenuNodeKey(menuItem));
|
|
616
|
+
iconPin.style.color = brandColor;
|
|
617
|
+
iconPin.style.transition = 'all 0.15s';
|
|
618
|
+
iconPin.style.opacity = '1';
|
|
619
|
+
this.#pinIconHoverTimerId.set(null);
|
|
620
|
+
}, this.#pinIconHoverTimerDelay));
|
|
621
|
+
}
|
|
622
|
+
}
|
|
560
623
|
if (!this.#menuFocusPipe.transform(this.currentPath(), menuItem)) {
|
|
561
|
-
const menuNode = event.currentTarget;
|
|
562
624
|
const iconMenu = menuNode.querySelector('.c-menu-node-icon');
|
|
563
625
|
const content = menuNode.querySelector('.c-menu-node-description-content');
|
|
564
626
|
const iconExpand = menuNode.querySelector('.c-menu-node-description-icon-expand');
|
|
@@ -566,7 +628,6 @@ class SidebarComponent {
|
|
|
566
628
|
if (menuNode) {
|
|
567
629
|
menuNode.style.transition = 'all 0.15s';
|
|
568
630
|
menuNode.style.backgroundColor = brandLightColorOpacity || 'rgba(248, 249, 250, 0.6)';
|
|
569
|
-
const brandColor = this.sidebar()?.brandColor || '#2962FF';
|
|
570
631
|
if (iconMenu) {
|
|
571
632
|
iconMenu.style.transition = 'all 0.15s';
|
|
572
633
|
iconMenu.style.color = brandColor;
|
|
@@ -583,8 +644,24 @@ class SidebarComponent {
|
|
|
583
644
|
}
|
|
584
645
|
};
|
|
585
646
|
onMouseLeaveMenuNode = (event, menuItem) => {
|
|
647
|
+
const menuNode = event.currentTarget;
|
|
648
|
+
// Nếu có bật config pin menu
|
|
649
|
+
if (this.sidebar()?.pin?.enabled) {
|
|
650
|
+
const iconPin = menuNode.querySelector('.c-menu-node-description-icon-pin');
|
|
651
|
+
if (iconPin) {
|
|
652
|
+
if (this.#pinIconHoverTimerId()) {
|
|
653
|
+
clearTimeout(this.#pinIconHoverTimerId());
|
|
654
|
+
this.#pinIconHoverTimerId.set(null);
|
|
655
|
+
}
|
|
656
|
+
this.#hoveredMenuNodeKey.set(null);
|
|
657
|
+
iconPin.style.transition = 'all 0.15s';
|
|
658
|
+
if (!this.isPinnedNode(menuItem)) {
|
|
659
|
+
iconPin.style.color = '#8C8C8C';
|
|
660
|
+
iconPin.style.opacity = '0';
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
586
664
|
if (!this.#menuFocusPipe.transform(this.currentPath(), menuItem)) {
|
|
587
|
-
const menuNode = event.currentTarget;
|
|
588
665
|
const iconMenu = menuNode.querySelector('.c-menu-node-icon');
|
|
589
666
|
const content = menuNode.querySelector('.c-menu-node-description-content');
|
|
590
667
|
const iconExpand = menuNode.querySelector('.c-menu-node-description-icon-expand');
|
|
@@ -609,6 +686,19 @@ class SidebarComponent {
|
|
|
609
686
|
// ==========================================
|
|
610
687
|
// PRIVATE LOGIC
|
|
611
688
|
// ==========================================
|
|
689
|
+
#setMenusByGroup = (menus) => {
|
|
690
|
+
this.menusByGroup.set(menus);
|
|
691
|
+
this.dataSource.data = menus;
|
|
692
|
+
};
|
|
693
|
+
#getMenuNodeKey = (node) => {
|
|
694
|
+
if (node?.id) {
|
|
695
|
+
return node.id;
|
|
696
|
+
}
|
|
697
|
+
if ('path' in node && node.path) {
|
|
698
|
+
return node.path;
|
|
699
|
+
}
|
|
700
|
+
return node.title || '';
|
|
701
|
+
};
|
|
612
702
|
#getMenuGroupByCurrentPath = (menus, menuGroup) => {
|
|
613
703
|
for (const menu of menus) {
|
|
614
704
|
if ('path' in menu && this.#isMenuPathMatchByCurrentPath(menu.path)) {
|
|
@@ -616,31 +706,68 @@ class SidebarComponent {
|
|
|
616
706
|
}
|
|
617
707
|
if ('children' in menu && menu.children?.length) {
|
|
618
708
|
const result = this.#getMenuGroupByCurrentPath(menu.children, menuGroup ?? menu);
|
|
619
|
-
if (result?.length)
|
|
709
|
+
if (result?.length) {
|
|
620
710
|
return result;
|
|
711
|
+
}
|
|
621
712
|
}
|
|
622
713
|
}
|
|
623
714
|
return [];
|
|
624
715
|
};
|
|
625
716
|
#bindingMenuGroupByCurrentPath = (menus) => {
|
|
626
|
-
|
|
627
|
-
if (!
|
|
717
|
+
// Chỉ bindingGroup mới khi người dùng không searchText
|
|
718
|
+
if (!this.#getValidSearchText()) {
|
|
719
|
+
const pinnedChildren = this.pinnedMenuGroup()?.children ?? [];
|
|
720
|
+
// Ưu tiên: Current path khớp với item trong pinMenuGroup thì lần đầu vào trang sẽ hiện pinnedMenuGroup
|
|
721
|
+
const isPinnedPathMatchValid = this.sidebar()?.pin?.enabled &&
|
|
722
|
+
pinnedChildren?.length &&
|
|
723
|
+
this.#getMenuGroupByCurrentPath(pinnedChildren)?.length &&
|
|
724
|
+
this.#isFirstBindingMenu() &&
|
|
725
|
+
this.idMenuGroupActive() !== this.pinnedMenuGroup()?.id;
|
|
726
|
+
if (isPinnedPathMatchValid) {
|
|
727
|
+
const pinned = this.pinnedMenuGroup();
|
|
728
|
+
this.idMenuGroupActive.set(pinned.id);
|
|
729
|
+
this.#layoutStorageService.lastActiveMenuGroupId.set(pinned.id ?? '');
|
|
730
|
+
this.titleMenuGroup.set(pinned.title);
|
|
731
|
+
this.#setMenusByGroup(pinnedChildren);
|
|
732
|
+
this.#expandParentNodesByCurrentPath(pinnedChildren);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
628
735
|
let menuGroupByPath = this.#getMenuGroupByCurrentPath(menus);
|
|
736
|
+
// Nếu không tìm được path nào khớp với menu
|
|
629
737
|
if (!menuGroupByPath?.length) {
|
|
630
738
|
const lastActiveId = this.#layoutStorageService.lastActiveMenuGroupId.get() || '';
|
|
739
|
+
// Nếu có pinned group thì hiện mậc định là pinnedMenuGroup
|
|
740
|
+
if (this.sidebar()?.pin?.enabled && lastActiveId === this.pinnedMenuGroup()?.id && pinnedChildren?.length) {
|
|
741
|
+
const pinned = this.pinnedMenuGroup();
|
|
742
|
+
this.idMenuGroupActive.set(pinned.id);
|
|
743
|
+
this.titleMenuGroup.set(pinned.title);
|
|
744
|
+
this.#setMenusByGroup(pinnedChildren);
|
|
745
|
+
this.#expandParentNodesByCurrentPath(pinnedChildren);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
// Nếu không có pinnedMenuGroup thì menuGroup lấy từ thao tác cuối cùng của người dùng
|
|
631
749
|
menuGroupByPath = this.menus()?.filter(menu => menu?.id === lastActiveId) || [];
|
|
632
750
|
}
|
|
751
|
+
// Kiểm tra lại menuGroupPath đã thực sự tìm được chưa?
|
|
633
752
|
if (menuGroupByPath?.length) {
|
|
634
|
-
|
|
635
|
-
this.
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
this.menusByGroup.set(matchedGroup.children);
|
|
640
|
-
this.#expandParentNodesByCurrentPath(this.menusByGroup());
|
|
753
|
+
// Nếu user đang ở pinedGroup và curentPath có chứa trong pinnedMenuGroup thì return luôn, không chuyển sang menuGroup mới
|
|
754
|
+
if (this.sidebar()?.pin?.enabled &&
|
|
755
|
+
this.idMenuGroupActive() === this.pinnedMenuGroup()?.id &&
|
|
756
|
+
this.#getMenuGroupByCurrentPath(pinnedChildren)?.length) {
|
|
757
|
+
return;
|
|
641
758
|
}
|
|
642
759
|
else {
|
|
643
|
-
|
|
760
|
+
const matchedGroup = menuGroupByPath[0];
|
|
761
|
+
this.idMenuGroupActive.set(matchedGroup?.id);
|
|
762
|
+
this.#layoutStorageService.lastActiveMenuGroupId.set(matchedGroup?.id || '');
|
|
763
|
+
this.titleMenuGroup.set(matchedGroup?.tooltipTitle || matchedGroup?.title);
|
|
764
|
+
if ('children' in matchedGroup && matchedGroup.children?.length) {
|
|
765
|
+
this.menusByGroup.set(matchedGroup.children);
|
|
766
|
+
this.#expandParentNodesByCurrentPath(this.menusByGroup());
|
|
767
|
+
}
|
|
768
|
+
else {
|
|
769
|
+
this.menusByGroup.set([]);
|
|
770
|
+
}
|
|
644
771
|
}
|
|
645
772
|
}
|
|
646
773
|
else {
|
|
@@ -668,14 +795,14 @@ class SidebarComponent {
|
|
|
668
795
|
return shouldPropagate;
|
|
669
796
|
}
|
|
670
797
|
#filterMenuBySearchText = (menus) => {
|
|
671
|
-
const
|
|
672
|
-
if (!
|
|
798
|
+
const validSearchText = this.#getValidSearchText();
|
|
799
|
+
if (!validSearchText) {
|
|
673
800
|
this.dataSource.data = menus;
|
|
674
801
|
this.#onCollapseAllMenuNodes(menus);
|
|
675
802
|
this.#expandParentNodesByCurrentPath(menus);
|
|
676
803
|
}
|
|
677
804
|
else {
|
|
678
|
-
const aliasSearchText = SdUtilities.changeAliasLowerCase(
|
|
805
|
+
const aliasSearchText = SdUtilities.changeAliasLowerCase(validSearchText);
|
|
679
806
|
this.dataSource.data = this.#getMenuByAliasSearchText(menus, aliasSearchText);
|
|
680
807
|
if (this.dataSource.data?.length) {
|
|
681
808
|
this.#onExpandAllMenuNodes(this.dataSource.data);
|
|
@@ -701,10 +828,12 @@ class SidebarComponent {
|
|
|
701
828
|
return result;
|
|
702
829
|
};
|
|
703
830
|
#isMenuPathMatchByCurrentPath = (path) => {
|
|
704
|
-
if (!path)
|
|
831
|
+
if (!path) {
|
|
705
832
|
return false;
|
|
706
|
-
|
|
833
|
+
}
|
|
834
|
+
if (this.currentPath() === path) {
|
|
707
835
|
return true;
|
|
836
|
+
}
|
|
708
837
|
return this.#normalizePath(this.currentPath()).startsWith(this.#normalizePath(path));
|
|
709
838
|
};
|
|
710
839
|
#normalizePath = (p) => (p.endsWith('/') ? p : p + '/');
|
|
@@ -712,8 +841,9 @@ class SidebarComponent {
|
|
|
712
841
|
this.showSideBar.emit(null);
|
|
713
842
|
}
|
|
714
843
|
#convertColor = (input, opacity = 1) => {
|
|
715
|
-
if (!input)
|
|
844
|
+
if (!input) {
|
|
716
845
|
return '';
|
|
846
|
+
}
|
|
717
847
|
input = input.trim();
|
|
718
848
|
const hexRegex = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
719
849
|
const rgbRegex = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i;
|
|
@@ -738,6 +868,10 @@ class SidebarComponent {
|
|
|
738
868
|
}
|
|
739
869
|
return input;
|
|
740
870
|
};
|
|
871
|
+
#getValidSearchText = () => {
|
|
872
|
+
const normalized = this.#normalizeSearchText(this.searchText());
|
|
873
|
+
return normalized && normalized.length >= 2 ? normalized : '';
|
|
874
|
+
};
|
|
741
875
|
#normalizeSearchText = (searchText) => {
|
|
742
876
|
let str = searchText?.toString() ?? '';
|
|
743
877
|
/* eslint-disable no-useless-escape */
|
|
@@ -759,7 +893,7 @@ class SidebarComponent {
|
|
|
759
893
|
return count;
|
|
760
894
|
};
|
|
761
895
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
762
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SidebarComponent, isStandalone: true, selector: "sidebar", inputs: { isShowSidebar: { classPropertyName: "isShowSidebar", publicName: "isShowSidebar", isSignal: true, isRequired: true, transformFunction: null }, menus: { classPropertyName: "menus", publicName: "menus", isSignal: true, isRequired: true, transformFunction: null }, userInfo: { classPropertyName: "userInfo", publicName: "userInfo", isSignal: true, isRequired: true, transformFunction: null }, sidebar: { classPropertyName: "sidebar", publicName: "sidebar", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { expandSideBar: "expandSideBar", popupUserMenuClosed: "popupUserMenuClosed", popupUserMenuOpened: "popupUserMenuOpened", showSideBar: "showSideBar" }, ngImport: i0, template: "@let _userInfo = userInfo();\r\n@let _sidebar = sidebar();\r\n\r\n@if (_userInfo && _sidebar) {\r\n <div class=\"wrapper\" [style.height]=\"isMobileOrTablet ? screenHeight + 'px' : '100%'\">\r\n <div class=\"c-header\">\r\n @if (_sidebar.logoUrl) {\r\n <div class=\"c-logo\">\r\n <a href=\"javascript:;\" (click)=\"openHomePage()\">\r\n <img alt=\"logo\" [src]=\"_sidebar.logoUrl\" />\r\n </a>\r\n </div>\r\n }\r\n <div class=\"c-title-menu-group\">\r\n <span>{{ titleMenuGroup() || _sidebar.defaultTitle || 'Back Office' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"c-body\">\r\n <div class=\"c-menu\">\r\n <div class=\"c-menu-group\">\r\n @for (nodeMenuGroup of menus(); track nodeMenuGroup.id) {\r\n <button\r\n (mouseenter)=\"onMouseOverMenuGroupNode($event, nodeMenuGroup)\"\r\n (mouseleave)=\"onMouseLeaveMenuGroupNode($event, nodeMenuGroup)\"\r\n (click)=\"expandMenuGroup(nodeMenuGroup)\"\r\n [matTooltip]=\"nodeMenuGroup.tooltipTitle || nodeMenuGroup.title\"\r\n [matTooltipClass]=\"'c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140'\"\r\n [matTooltipPosition]=\"'right'\"\r\n style=\"padding: 0; margin: 0; border: none; background-color: transparent\">\r\n @if (nodeMenuGroup.iconUrl) {\r\n <span\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n backgroundColor: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n <img width=\"24px\" height=\"24px\" [src]=\"nodeMenuGroup.iconUrl\" [alt]=\"nodeMenuGroup.title\" />\r\n </span>\r\n } @else {\r\n <mat-icon\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n color: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandColor || '#2962FF' : '#8C8C8C',\r\n backgroundColor: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n {{ nodeMenuGroup.icon || 'widgets' }}\r\n </mat-icon>\r\n }\r\n </button>\r\n }\r\n </div>\r\n <div class=\"c-menu-tree\">\r\n @if (totalMenuInMenusByGroup() >= 10) {\r\n <div style=\"padding: 0px 4px\" class=\"c-menu-tree-search\">\r\n <sd-input size=\"sm\" [placeholder]=\"'core.module.layout.sidebar.search' | translate\" [model]=\"searchText()\" (sdChange)=\"onFilterSearchText($event)\">\r\n <ng-template sdSuffixDef>\r\n @if (searchText()) {\r\n <mat-icon class=\"c-search-prefix-icon cancel\" (click)=\"onClearSearchText()\">cancel</mat-icon>\r\n } @else {\r\n <mat-icon class=\"c-search-prefix-icon search\">search</mat-icon>\r\n }\r\n </ng-template>\r\n </sd-input>\r\n </div>\r\n }\r\n <div class=\"c-menu-tree-container\">\r\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\" [style.backgroundColor]=\"'transparent'\">\r\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: !hasChild\">\r\n <li\r\n class=\"c-menu-node\"\r\n (mouseenter)=\"onMouseOverMenuNode($event, node)\"\r\n (mouseleave)=\"onMouseLeaveMenuNode($event, node)\"\r\n [ngStyle]=\"{\r\n backgroundColor: (currentPath() | menuFocus: node) ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n <div aria-hidden=\"true\" class=\"c-menu-node-description\" (click)=\"navigate(node)\" [class.d-none]=\"!isShowSidebar()\">\r\n <div\r\n class=\"c-menu-node-description-content\"\r\n [ngStyle]=\"{\r\n color: (currentPath() | menuFocus: node) ? _sidebar.brandColor || '#2962FF' : '#1F1F1F',\r\n }\"\r\n [innerHTML]=\"node.title | highLightSearch: searchText() | sdSafeHtml\"></div>\r\n </div>\r\n </li>\r\n </mat-nested-tree-node>\r\n\r\n <mat-nested-tree-node\r\n *matTreeNodeDef=\"let node; when: hasChild\"\r\n aria-hidden=\"true\"\r\n [class]=\"{ expanded: treeControl.isExpanded(node), isfocus: currentPath() | menuFocus: node }\">\r\n <li>\r\n <div\r\n class=\"c-menu-node\"\r\n (mouseenter)=\"onMouseOverMenuNode($event, node)\"\r\n (mouseleave)=\"onMouseLeaveMenuNode($event, node)\">\r\n <div class=\"d-flex align-items-center\" style=\"gap: 10px; width: 100%\">\r\n <div [class.d-none]=\"!isShowSidebar()\" class=\"c-menu-node-description\" (click)=\"onToggleMenuNode(node)\">\r\n <div\r\n class=\"c-menu-node-description-content\"\r\n [innerHTML]=\"node.title | highLightSearch: searchText() | sdSafeHtml\"></div>\r\n <mat-icon class=\"c-menu-node-description-icon-expand\">\r\n {{ treeControl.isExpanded(node) ? 'keyboard_arrow_up' : 'keyboard_arrow_down' }}\r\n </mat-icon>\r\n </div>\r\n </div>\r\n </div>\r\n <ul class=\"p-0\" [class.d-none]=\"!treeControl.isExpanded(node)\">\r\n <ng-container matTreeNodeOutlet></ng-container>\r\n </ul>\r\n </li>\r\n </mat-nested-tree-node>\r\n </mat-tree>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"c-footer\">\r\n <lib-layout-user\r\n [userInfo]=\"_userInfo\"\r\n [isMobileOrTablet]=\"isMobileOrTablet\"\r\n (menuOpened)=\"onUserMenuOpened()\"\r\n (menuClosed)=\"onUserMenuClosed()\"\r\n [isShowSidebar]=\"isShowSidebar()\"\r\n (toggleMenuLock)=\"toggleMenuLock($event)\">\r\n </lib-layout-user>\r\n </div>\r\n\r\n <div class=\"c-vertical\"></div>\r\n </div>\r\n}", styles: ["::ng-deep .mat-mdc-tooltip-panel:has(.c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140){pointer-events:none}:host ::ng-deep .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:16px!important}:host ::ng-deep .mat-nested-tree-node ul .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:32px!important}:host ::ng-deep .mat-nested-tree-node ul .mat-nested-tree-node ul .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:48px!important}ul,li{margin-top:0;margin-bottom:0;list-style-type:none}.wrapper{display:flex;flex-direction:column;width:290px;background-color:#fff}.wrapper .c-header{display:flex;align-items:center;height:52px;padding:3px;gap:16px}.wrapper .c-header .c-logo{display:flex;justify-content:center;align-items:center;width:52px;height:52px}.wrapper .c-header .c-logo img{width:32px;height:32px;object-fit:cover}.wrapper .c-header .c-title-menu-group{display:flex;align-items:center;font-size:18px;font-weight:500;flex:1}.wrapper .c-body{flex:1;overflow-y:hidden}.wrapper .c-body .c-menu{height:100%;display:flex}.wrapper .c-body .c-menu .c-menu-group{display:flex;flex-direction:column;align-items:center;width:60px;overflow-y:scroll;scrollbar-width:none}.wrapper .c-body .c-menu .c-menu-group .c-menu-group-icon{display:flex;justify-content:center;align-items:center;min-height:50px;width:52px;border-radius:8px;transition:all .15s}.wrapper .c-body .c-menu .c-menu-group .c-menu-group-icon img{height:24px;width:24px;object-fit:contain}.wrapper .c-body .c-menu .c-menu-tree{flex:1;display:flex;flex-direction:column;padding:3px 4px 3px 3px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon{cursor:pointer;color:#757575;padding:0}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon.search{width:20px;height:20px;font-size:18px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon.cancel{width:16px;height:16px;font-size:16px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container{flex:1;overflow-y:scroll;scrollbar-width:none}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node{width:100%;display:flex;cursor:pointer;min-height:44px;padding:8px;border-radius:8px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-icon{display:flex;justify-content:center;align-items:center;height:100%}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description{flex:1;display:flex;align-items:center}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-content{flex:1;display:flex;align-items:center;flex-wrap:wrap;white-space:pre-wrap;font-size:15px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-icon-expand{text-align:left;background-color:transparent;border:none;font-size:20px}.wrapper .c-footer{height:80px}.wrapper .c-vertical{position:fixed;height:100vh;left:58px;width:2px;background-color:#f8f9fa;pointer-events:none}\n"], dependencies: [{ kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "tooltip", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "sdFocusForceBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTreeModule }, { kind: "directive", type: i3.MatNestedTreeNode, selector: "mat-nested-tree-node", inputs: ["matNestedTreeNode", "disabled", "tabIndex"], outputs: ["activation", "expandedChange"], exportAs: ["matNestedTreeNode"] }, { kind: "directive", type: i3.MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "component", type: i3.MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: i3.MatTreeNodeOutlet, selector: "[matTreeNodeOutlet]" }, { kind: "pipe", type: SdSafeHtmlPipe, name: "sdSafeHtml" }, { kind: "ngmodule", type: MatInputModule }, { kind: "pipe", type: MenuFocusPipe, name: "menuFocus" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: HighlightSearchPipe, name: "highLightSearch" }, { kind: "directive", type: SdSuffixDefDirective, selector: "[sdSuffixDef]" }, { kind: "component", type: LayoutUserComponent$1, selector: "lib-layout-user", inputs: ["isMobileOrTablet", "isMenuLock", "isShowSidebar", "userInfo"], outputs: ["menuClosed", "menuOpened", "toggleMenuLock"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
896
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SidebarComponent, isStandalone: true, selector: "sidebar", inputs: { isShowSidebar: { classPropertyName: "isShowSidebar", publicName: "isShowSidebar", isSignal: true, isRequired: true, transformFunction: null }, menus: { classPropertyName: "menus", publicName: "menus", isSignal: true, isRequired: true, transformFunction: null }, userInfo: { classPropertyName: "userInfo", publicName: "userInfo", isSignal: true, isRequired: true, transformFunction: null }, sidebar: { classPropertyName: "sidebar", publicName: "sidebar", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { expandSideBar: "expandSideBar", popupUserMenuClosed: "popupUserMenuClosed", popupUserMenuOpened: "popupUserMenuOpened", showSideBar: "showSideBar" }, ngImport: i0, template: "@let _userInfo = userInfo();\r\n@let _sidebar = sidebar();\r\n\r\n@if (_userInfo && _sidebar) {\r\n <div class=\"wrapper\" [style.height]=\"isMobileOrTablet ? screenHeight + 'px' : '100%'\">\r\n <div class=\"c-header\">\r\n @if (_sidebar.logoUrl) {\r\n <div class=\"c-logo\">\r\n <a href=\"javascript:;\" (click)=\"openHomePage()\">\r\n <img alt=\"logo\" [src]=\"_sidebar.logoUrl\" />\r\n </a>\r\n </div>\r\n }\r\n <div class=\"c-title-menu-group\">\r\n <span>{{ titleMenuGroup() || _sidebar.defaultTitle || 'Back Office' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"c-body\">\r\n <div class=\"c-menu\">\r\n <div class=\"c-menu-group\">\r\n @if (_sidebar?.pin?.enabled && pinnedMenuGroup()?.children?.length) {\r\n <button\r\n (mouseenter)=\"onMouseOverMenuGroupNode($event, pinnedMenuGroup())\"\r\n (mouseleave)=\"onMouseLeaveMenuGroupNode($event, pinnedMenuGroup())\"\r\n (click)=\"expandPinnedGroup()\"\r\n [matTooltip]=\"'\u0110\u00E3 ghim'\"\r\n [matTooltipClass]=\"'c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140'\"\r\n [matTooltipPosition]=\"'right'\"\r\n style=\"padding: 0; margin: 0; border: none; background-color: transparent\">\r\n <mat-icon\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n color: isPinnedMenuGroupActive() ? _sidebar.brandColor || '#2962FF' : '#8C8C8C',\r\n backgroundColor: isPinnedMenuGroupActive() ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n push_pin\r\n </mat-icon>\r\n </button>\r\n }\r\n @for (nodeMenuGroup of menus(); track nodeMenuGroup.id) {\r\n <button\r\n (mouseenter)=\"onMouseOverMenuGroupNode($event, nodeMenuGroup)\"\r\n (mouseleave)=\"onMouseLeaveMenuGroupNode($event, nodeMenuGroup)\"\r\n (click)=\"expandMenuGroup(nodeMenuGroup)\"\r\n [matTooltip]=\"nodeMenuGroup.tooltipTitle || nodeMenuGroup.title\"\r\n [matTooltipClass]=\"'c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140'\"\r\n [matTooltipPosition]=\"'right'\"\r\n style=\"padding: 0; margin: 0; border: none; background-color: transparent\">\r\n @if (nodeMenuGroup.iconUrl) {\r\n <span\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n backgroundColor: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n <img width=\"24px\" height=\"24px\" [src]=\"nodeMenuGroup.iconUrl\" [alt]=\"nodeMenuGroup.title\" />\r\n </span>\r\n } @else {\r\n <mat-icon\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n color: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandColor || '#2962FF' : '#8C8C8C',\r\n backgroundColor: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n {{ nodeMenuGroup.icon || 'widgets' }}\r\n </mat-icon>\r\n }\r\n </button>\r\n }\r\n </div>\r\n <div class=\"c-menu-tree\">\r\n @if (totalMenuInMenusByGroup() >= 10) {\r\n <div style=\"padding: 0px 4px\" class=\"c-menu-tree-search\">\r\n <sd-input size=\"sm\" [placeholder]=\"'core.module.layout.sidebar.search' | translate\" [model]=\"searchText()\" (sdChange)=\"onFilterSearchText($event)\">\r\n <ng-template sdSuffixDef>\r\n @if (searchText()) {\r\n <mat-icon class=\"c-search-prefix-icon cancel\" (click)=\"onClearSearchText()\">cancel</mat-icon>\r\n } @else {\r\n <mat-icon class=\"c-search-prefix-icon search\">search</mat-icon>\r\n }\r\n </ng-template>\r\n </sd-input>\r\n </div>\r\n }\r\n <div class=\"c-menu-tree-container\">\r\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\" [style.backgroundColor]=\"'transparent'\">\r\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: !hasChild\">\r\n <li\r\n class=\"c-menu-node\"\r\n (mouseenter)=\"onMouseOverMenuNode($event, node)\"\r\n (mouseleave)=\"onMouseLeaveMenuNode($event, node)\"\r\n [ngStyle]=\"{\r\n backgroundColor: (currentPath() | menuFocus: node) ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n <div aria-hidden=\"true\" class=\"c-menu-node-description\" (click)=\"navigate(node)\" [class.d-none]=\"!isShowSidebar()\">\r\n <div\r\n class=\"c-menu-node-description-content\"\r\n [ngStyle]=\"{\r\n color: (currentPath() | menuFocus: node) ? _sidebar.brandColor || '#2962FF' : '#1F1F1F',\r\n }\"\r\n [innerHTML]=\"node.title | highLightSearch: searchText() | sdSafeHtml\"></div>\r\n\r\n @if (_sidebar?.pin?.enabled) {\r\n <mat-icon\r\n class=\"c-menu-node-description-icon-pin\"\r\n [fontSet]=\"isPinnedNode(node) ? 'material-icons' : 'material-icons-outlined'\"\r\n [style.opacity]=\"isPinnedNode(node) || isHoveredNode(node) ? '1' : null\"\r\n [style.color]=\"isPinnedNode(node) || isHoveredNode(node) ? sidebar()?.brandColor || '#2962FF' : null\"\r\n (click)=\"onTogglePin($event, node)\"\r\n >push_pin\r\n </mat-icon>\r\n }\r\n </div>\r\n </li>\r\n </mat-nested-tree-node>\r\n\r\n <mat-nested-tree-node\r\n *matTreeNodeDef=\"let node; when: hasChild\"\r\n aria-hidden=\"true\"\r\n [class]=\"{ expanded: treeControl.isExpanded(node), isfocus: currentPath() | menuFocus: node }\">\r\n <li>\r\n <div\r\n class=\"c-menu-node\"\r\n (mouseenter)=\"onMouseOverMenuNode($event, node)\"\r\n (mouseleave)=\"onMouseLeaveMenuNode($event, node)\">\r\n <div class=\"d-flex align-items-center\" style=\"gap: 10px; width: 100%\">\r\n <div [class.d-none]=\"!isShowSidebar()\" class=\"c-menu-node-description\" (click)=\"onToggleMenuNode(node)\">\r\n <div\r\n class=\"c-menu-node-description-content\"\r\n [innerHTML]=\"node.title | highLightSearch: searchText() | sdSafeHtml\"></div>\r\n <mat-icon class=\"c-menu-node-description-icon-expand\">\r\n {{ treeControl.isExpanded(node) ? 'keyboard_arrow_up' : 'keyboard_arrow_down' }}\r\n </mat-icon>\r\n </div>\r\n </div>\r\n </div>\r\n <ul class=\"p-0\" [class.d-none]=\"!treeControl.isExpanded(node)\">\r\n <ng-container matTreeNodeOutlet></ng-container>\r\n </ul>\r\n </li>\r\n </mat-nested-tree-node>\r\n </mat-tree>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"c-footer\">\r\n <lib-layout-user\r\n [userInfo]=\"_userInfo\"\r\n [isMobileOrTablet]=\"isMobileOrTablet\"\r\n (menuOpened)=\"onUserMenuOpened()\"\r\n (menuClosed)=\"onUserMenuClosed()\"\r\n [isShowSidebar]=\"isShowSidebar()\"\r\n (toggleMenuLock)=\"toggleMenuLock($event)\">\r\n </lib-layout-user>\r\n </div>\r\n\r\n <div class=\"c-vertical\"></div>\r\n </div>\r\n}\r\n", styles: ["::ng-deep .mat-mdc-tooltip-panel:has(.c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140){pointer-events:none}:host ::ng-deep .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:16px!important}:host ::ng-deep .mat-nested-tree-node ul .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:32px!important}:host ::ng-deep .mat-nested-tree-node ul .mat-nested-tree-node ul .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:48px!important}ul,li{margin-top:0;margin-bottom:0;list-style-type:none}.wrapper{display:flex;flex-direction:column;width:290px;background-color:#fff}.wrapper .c-header{display:flex;align-items:center;height:52px;padding:3px;gap:16px}.wrapper .c-header .c-logo{display:flex;justify-content:center;align-items:center;width:52px;height:52px}.wrapper .c-header .c-logo img{width:32px;height:32px;object-fit:cover}.wrapper .c-header .c-title-menu-group{display:flex;align-items:center;font-size:18px;font-weight:500;flex:1}.wrapper .c-body{flex:1;overflow-y:hidden}.wrapper .c-body .c-menu{height:100%;display:flex}.wrapper .c-body .c-menu .c-menu-group{display:flex;flex-direction:column;align-items:center;width:60px;overflow-y:scroll;scrollbar-width:none}.wrapper .c-body .c-menu .c-menu-group .c-menu-group-icon{display:flex;justify-content:center;align-items:center;min-height:50px;width:52px;border-radius:8px;transition:all .15s}.wrapper .c-body .c-menu .c-menu-group .c-menu-group-icon img{height:24px;width:24px;object-fit:contain}.wrapper .c-body .c-menu .c-menu-tree{flex:1;display:flex;flex-direction:column;padding:3px 4px 3px 3px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon{cursor:pointer;color:#757575;padding:0}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon.search{width:20px;height:20px;font-size:18px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon.cancel{width:16px;height:16px;font-size:16px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container{flex:1;overflow-y:scroll;scrollbar-width:none}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node{width:100%;display:flex;cursor:pointer;min-height:44px;padding:8px;border-radius:8px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-icon{display:flex;justify-content:center;align-items:center;height:100%}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description{flex:1;display:flex;align-items:center}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-content{flex:1;display:flex;align-items:center;flex-wrap:wrap;white-space:pre-wrap;font-size:15px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-icon-expand{display:flex;align-items:center;justify-content:start;background-color:transparent;border:none;font-size:20px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-icon-pin{display:flex;align-items:center;justify-content:start;background-color:transparent;border:none;font-size:18px;opacity:0}.wrapper .c-footer{height:80px}.wrapper .c-vertical{position:fixed;height:100vh;left:58px;width:2px;background-color:#f8f9fa;pointer-events:none}\n"], dependencies: [{ kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "tooltip", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "sdFocusForceBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTreeModule }, { kind: "directive", type: i3.MatNestedTreeNode, selector: "mat-nested-tree-node", inputs: ["matNestedTreeNode", "disabled", "tabIndex"], outputs: ["activation", "expandedChange"], exportAs: ["matNestedTreeNode"] }, { kind: "directive", type: i3.MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "component", type: i3.MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: i3.MatTreeNodeOutlet, selector: "[matTreeNodeOutlet]" }, { kind: "pipe", type: SdSafeHtmlPipe, name: "sdSafeHtml" }, { kind: "ngmodule", type: MatInputModule }, { kind: "pipe", type: MenuFocusPipe, name: "menuFocus" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: HighlightSearchPipe, name: "highLightSearch" }, { kind: "directive", type: SdSuffixDefDirective, selector: "[sdSuffixDef]" }, { kind: "component", type: LayoutUserComponent$1, selector: "lib-layout-user", inputs: ["isMobileOrTablet", "isMenuLock", "isShowSidebar", "userInfo"], outputs: ["menuClosed", "menuOpened", "toggleMenuLock"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
763
897
|
}
|
|
764
898
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SidebarComponent, decorators: [{
|
|
765
899
|
type: Component,
|
|
@@ -778,7 +912,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
|
|
|
778
912
|
SdSuffixDefDirective,
|
|
779
913
|
LayoutUserComponent$1,
|
|
780
914
|
TranslatePipe,
|
|
781
|
-
], template: "@let _userInfo = userInfo();\r\n@let _sidebar = sidebar();\r\n\r\n@if (_userInfo && _sidebar) {\r\n <div class=\"wrapper\" [style.height]=\"isMobileOrTablet ? screenHeight + 'px' : '100%'\">\r\n <div class=\"c-header\">\r\n @if (_sidebar.logoUrl) {\r\n <div class=\"c-logo\">\r\n <a href=\"javascript:;\" (click)=\"openHomePage()\">\r\n <img alt=\"logo\" [src]=\"_sidebar.logoUrl\" />\r\n </a>\r\n </div>\r\n }\r\n <div class=\"c-title-menu-group\">\r\n <span>{{ titleMenuGroup() || _sidebar.defaultTitle || 'Back Office' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"c-body\">\r\n <div class=\"c-menu\">\r\n <div class=\"c-menu-group\">\r\n @for (nodeMenuGroup of menus(); track nodeMenuGroup.id) {\r\n <button\r\n (mouseenter)=\"onMouseOverMenuGroupNode($event, nodeMenuGroup)\"\r\n (mouseleave)=\"onMouseLeaveMenuGroupNode($event, nodeMenuGroup)\"\r\n (click)=\"expandMenuGroup(nodeMenuGroup)\"\r\n [matTooltip]=\"nodeMenuGroup.tooltipTitle || nodeMenuGroup.title\"\r\n [matTooltipClass]=\"'c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140'\"\r\n [matTooltipPosition]=\"'right'\"\r\n style=\"padding: 0; margin: 0; border: none; background-color: transparent\">\r\n @if (nodeMenuGroup.iconUrl) {\r\n <span\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n backgroundColor: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n <img width=\"24px\" height=\"24px\" [src]=\"nodeMenuGroup.iconUrl\" [alt]=\"nodeMenuGroup.title\" />\r\n </span>\r\n } @else {\r\n <mat-icon\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n color: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandColor || '#2962FF' : '#8C8C8C',\r\n backgroundColor: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n {{ nodeMenuGroup.icon || 'widgets' }}\r\n </mat-icon>\r\n }\r\n </button>\r\n }\r\n </div>\r\n <div class=\"c-menu-tree\">\r\n @if (totalMenuInMenusByGroup() >= 10) {\r\n <div style=\"padding: 0px 4px\" class=\"c-menu-tree-search\">\r\n <sd-input size=\"sm\" [placeholder]=\"'core.module.layout.sidebar.search' | translate\" [model]=\"searchText()\" (sdChange)=\"onFilterSearchText($event)\">\r\n <ng-template sdSuffixDef>\r\n @if (searchText()) {\r\n <mat-icon class=\"c-search-prefix-icon cancel\" (click)=\"onClearSearchText()\">cancel</mat-icon>\r\n } @else {\r\n <mat-icon class=\"c-search-prefix-icon search\">search</mat-icon>\r\n }\r\n </ng-template>\r\n </sd-input>\r\n </div>\r\n }\r\n <div class=\"c-menu-tree-container\">\r\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\" [style.backgroundColor]=\"'transparent'\">\r\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: !hasChild\">\r\n <li\r\n class=\"c-menu-node\"\r\n (mouseenter)=\"onMouseOverMenuNode($event, node)\"\r\n (mouseleave)=\"onMouseLeaveMenuNode($event, node)\"\r\n [ngStyle]=\"{\r\n backgroundColor: (currentPath() | menuFocus: node) ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n <div aria-hidden=\"true\" class=\"c-menu-node-description\" (click)=\"navigate(node)\" [class.d-none]=\"!isShowSidebar()\">\r\n <div\r\n class=\"c-menu-node-description-content\"\r\n [ngStyle]=\"{\r\n color: (currentPath() | menuFocus: node) ? _sidebar.brandColor || '#2962FF' : '#1F1F1F',\r\n }\"\r\n [innerHTML]=\"node.title | highLightSearch: searchText() | sdSafeHtml\"></div>\r\n </div>\r\n </li>\r\n </mat-nested-tree-node>\r\n\r\n <mat-nested-tree-node\r\n *matTreeNodeDef=\"let node; when: hasChild\"\r\n aria-hidden=\"true\"\r\n [class]=\"{ expanded: treeControl.isExpanded(node), isfocus: currentPath() | menuFocus: node }\">\r\n <li>\r\n <div\r\n class=\"c-menu-node\"\r\n (mouseenter)=\"onMouseOverMenuNode($event, node)\"\r\n (mouseleave)=\"onMouseLeaveMenuNode($event, node)\">\r\n <div class=\"d-flex align-items-center\" style=\"gap: 10px; width: 100%\">\r\n <div [class.d-none]=\"!isShowSidebar()\" class=\"c-menu-node-description\" (click)=\"onToggleMenuNode(node)\">\r\n <div\r\n class=\"c-menu-node-description-content\"\r\n [innerHTML]=\"node.title | highLightSearch: searchText() | sdSafeHtml\"></div>\r\n <mat-icon class=\"c-menu-node-description-icon-expand\">\r\n {{ treeControl.isExpanded(node) ? 'keyboard_arrow_up' : 'keyboard_arrow_down' }}\r\n </mat-icon>\r\n </div>\r\n </div>\r\n </div>\r\n <ul class=\"p-0\" [class.d-none]=\"!treeControl.isExpanded(node)\">\r\n <ng-container matTreeNodeOutlet></ng-container>\r\n </ul>\r\n </li>\r\n </mat-nested-tree-node>\r\n </mat-tree>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"c-footer\">\r\n <lib-layout-user\r\n [userInfo]=\"_userInfo\"\r\n [isMobileOrTablet]=\"isMobileOrTablet\"\r\n (menuOpened)=\"onUserMenuOpened()\"\r\n (menuClosed)=\"onUserMenuClosed()\"\r\n [isShowSidebar]=\"isShowSidebar()\"\r\n (toggleMenuLock)=\"toggleMenuLock($event)\">\r\n </lib-layout-user>\r\n </div>\r\n\r\n <div class=\"c-vertical\"></div>\r\n </div>\r\n}", styles: ["::ng-deep .mat-mdc-tooltip-panel:has(.c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140){pointer-events:none}:host ::ng-deep .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:16px!important}:host ::ng-deep .mat-nested-tree-node ul .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:32px!important}:host ::ng-deep .mat-nested-tree-node ul .mat-nested-tree-node ul .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:48px!important}ul,li{margin-top:0;margin-bottom:0;list-style-type:none}.wrapper{display:flex;flex-direction:column;width:290px;background-color:#fff}.wrapper .c-header{display:flex;align-items:center;height:52px;padding:3px;gap:16px}.wrapper .c-header .c-logo{display:flex;justify-content:center;align-items:center;width:52px;height:52px}.wrapper .c-header .c-logo img{width:32px;height:32px;object-fit:cover}.wrapper .c-header .c-title-menu-group{display:flex;align-items:center;font-size:18px;font-weight:500;flex:1}.wrapper .c-body{flex:1;overflow-y:hidden}.wrapper .c-body .c-menu{height:100%;display:flex}.wrapper .c-body .c-menu .c-menu-group{display:flex;flex-direction:column;align-items:center;width:60px;overflow-y:scroll;scrollbar-width:none}.wrapper .c-body .c-menu .c-menu-group .c-menu-group-icon{display:flex;justify-content:center;align-items:center;min-height:50px;width:52px;border-radius:8px;transition:all .15s}.wrapper .c-body .c-menu .c-menu-group .c-menu-group-icon img{height:24px;width:24px;object-fit:contain}.wrapper .c-body .c-menu .c-menu-tree{flex:1;display:flex;flex-direction:column;padding:3px 4px 3px 3px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon{cursor:pointer;color:#757575;padding:0}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon.search{width:20px;height:20px;font-size:18px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon.cancel{width:16px;height:16px;font-size:16px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container{flex:1;overflow-y:scroll;scrollbar-width:none}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node{width:100%;display:flex;cursor:pointer;min-height:44px;padding:8px;border-radius:8px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-icon{display:flex;justify-content:center;align-items:center;height:100%}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description{flex:1;display:flex;align-items:center}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-content{flex:1;display:flex;align-items:center;flex-wrap:wrap;white-space:pre-wrap;font-size:15px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-icon-expand{text-align:left;background-color:transparent;border:none;font-size:20px}.wrapper .c-footer{height:80px}.wrapper .c-vertical{position:fixed;height:100vh;left:58px;width:2px;background-color:#f8f9fa;pointer-events:none}\n"] }]
|
|
915
|
+
], template: "@let _userInfo = userInfo();\r\n@let _sidebar = sidebar();\r\n\r\n@if (_userInfo && _sidebar) {\r\n <div class=\"wrapper\" [style.height]=\"isMobileOrTablet ? screenHeight + 'px' : '100%'\">\r\n <div class=\"c-header\">\r\n @if (_sidebar.logoUrl) {\r\n <div class=\"c-logo\">\r\n <a href=\"javascript:;\" (click)=\"openHomePage()\">\r\n <img alt=\"logo\" [src]=\"_sidebar.logoUrl\" />\r\n </a>\r\n </div>\r\n }\r\n <div class=\"c-title-menu-group\">\r\n <span>{{ titleMenuGroup() || _sidebar.defaultTitle || 'Back Office' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"c-body\">\r\n <div class=\"c-menu\">\r\n <div class=\"c-menu-group\">\r\n @if (_sidebar?.pin?.enabled && pinnedMenuGroup()?.children?.length) {\r\n <button\r\n (mouseenter)=\"onMouseOverMenuGroupNode($event, pinnedMenuGroup())\"\r\n (mouseleave)=\"onMouseLeaveMenuGroupNode($event, pinnedMenuGroup())\"\r\n (click)=\"expandPinnedGroup()\"\r\n [matTooltip]=\"'\u0110\u00E3 ghim'\"\r\n [matTooltipClass]=\"'c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140'\"\r\n [matTooltipPosition]=\"'right'\"\r\n style=\"padding: 0; margin: 0; border: none; background-color: transparent\">\r\n <mat-icon\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n color: isPinnedMenuGroupActive() ? _sidebar.brandColor || '#2962FF' : '#8C8C8C',\r\n backgroundColor: isPinnedMenuGroupActive() ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n push_pin\r\n </mat-icon>\r\n </button>\r\n }\r\n @for (nodeMenuGroup of menus(); track nodeMenuGroup.id) {\r\n <button\r\n (mouseenter)=\"onMouseOverMenuGroupNode($event, nodeMenuGroup)\"\r\n (mouseleave)=\"onMouseLeaveMenuGroupNode($event, nodeMenuGroup)\"\r\n (click)=\"expandMenuGroup(nodeMenuGroup)\"\r\n [matTooltip]=\"nodeMenuGroup.tooltipTitle || nodeMenuGroup.title\"\r\n [matTooltipClass]=\"'c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140'\"\r\n [matTooltipPosition]=\"'right'\"\r\n style=\"padding: 0; margin: 0; border: none; background-color: transparent\">\r\n @if (nodeMenuGroup.iconUrl) {\r\n <span\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n backgroundColor: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n <img width=\"24px\" height=\"24px\" [src]=\"nodeMenuGroup.iconUrl\" [alt]=\"nodeMenuGroup.title\" />\r\n </span>\r\n } @else {\r\n <mat-icon\r\n class=\"c-menu-group-icon\"\r\n [ngStyle]=\"{\r\n color: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandColor || '#2962FF' : '#8C8C8C',\r\n backgroundColor: idMenuGroupActive() === nodeMenuGroup?.id ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n {{ nodeMenuGroup.icon || 'widgets' }}\r\n </mat-icon>\r\n }\r\n </button>\r\n }\r\n </div>\r\n <div class=\"c-menu-tree\">\r\n @if (totalMenuInMenusByGroup() >= 10) {\r\n <div style=\"padding: 0px 4px\" class=\"c-menu-tree-search\">\r\n <sd-input size=\"sm\" [placeholder]=\"'core.module.layout.sidebar.search' | translate\" [model]=\"searchText()\" (sdChange)=\"onFilterSearchText($event)\">\r\n <ng-template sdSuffixDef>\r\n @if (searchText()) {\r\n <mat-icon class=\"c-search-prefix-icon cancel\" (click)=\"onClearSearchText()\">cancel</mat-icon>\r\n } @else {\r\n <mat-icon class=\"c-search-prefix-icon search\">search</mat-icon>\r\n }\r\n </ng-template>\r\n </sd-input>\r\n </div>\r\n }\r\n <div class=\"c-menu-tree-container\">\r\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\" [style.backgroundColor]=\"'transparent'\">\r\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: !hasChild\">\r\n <li\r\n class=\"c-menu-node\"\r\n (mouseenter)=\"onMouseOverMenuNode($event, node)\"\r\n (mouseleave)=\"onMouseLeaveMenuNode($event, node)\"\r\n [ngStyle]=\"{\r\n backgroundColor: (currentPath() | menuFocus: node) ? _sidebar.brandLightColor || '#F8F9FA' : 'transparent',\r\n }\">\r\n <div aria-hidden=\"true\" class=\"c-menu-node-description\" (click)=\"navigate(node)\" [class.d-none]=\"!isShowSidebar()\">\r\n <div\r\n class=\"c-menu-node-description-content\"\r\n [ngStyle]=\"{\r\n color: (currentPath() | menuFocus: node) ? _sidebar.brandColor || '#2962FF' : '#1F1F1F',\r\n }\"\r\n [innerHTML]=\"node.title | highLightSearch: searchText() | sdSafeHtml\"></div>\r\n\r\n @if (_sidebar?.pin?.enabled) {\r\n <mat-icon\r\n class=\"c-menu-node-description-icon-pin\"\r\n [fontSet]=\"isPinnedNode(node) ? 'material-icons' : 'material-icons-outlined'\"\r\n [style.opacity]=\"isPinnedNode(node) || isHoveredNode(node) ? '1' : null\"\r\n [style.color]=\"isPinnedNode(node) || isHoveredNode(node) ? sidebar()?.brandColor || '#2962FF' : null\"\r\n (click)=\"onTogglePin($event, node)\"\r\n >push_pin\r\n </mat-icon>\r\n }\r\n </div>\r\n </li>\r\n </mat-nested-tree-node>\r\n\r\n <mat-nested-tree-node\r\n *matTreeNodeDef=\"let node; when: hasChild\"\r\n aria-hidden=\"true\"\r\n [class]=\"{ expanded: treeControl.isExpanded(node), isfocus: currentPath() | menuFocus: node }\">\r\n <li>\r\n <div\r\n class=\"c-menu-node\"\r\n (mouseenter)=\"onMouseOverMenuNode($event, node)\"\r\n (mouseleave)=\"onMouseLeaveMenuNode($event, node)\">\r\n <div class=\"d-flex align-items-center\" style=\"gap: 10px; width: 100%\">\r\n <div [class.d-none]=\"!isShowSidebar()\" class=\"c-menu-node-description\" (click)=\"onToggleMenuNode(node)\">\r\n <div\r\n class=\"c-menu-node-description-content\"\r\n [innerHTML]=\"node.title | highLightSearch: searchText() | sdSafeHtml\"></div>\r\n <mat-icon class=\"c-menu-node-description-icon-expand\">\r\n {{ treeControl.isExpanded(node) ? 'keyboard_arrow_up' : 'keyboard_arrow_down' }}\r\n </mat-icon>\r\n </div>\r\n </div>\r\n </div>\r\n <ul class=\"p-0\" [class.d-none]=\"!treeControl.isExpanded(node)\">\r\n <ng-container matTreeNodeOutlet></ng-container>\r\n </ul>\r\n </li>\r\n </mat-nested-tree-node>\r\n </mat-tree>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"c-footer\">\r\n <lib-layout-user\r\n [userInfo]=\"_userInfo\"\r\n [isMobileOrTablet]=\"isMobileOrTablet\"\r\n (menuOpened)=\"onUserMenuOpened()\"\r\n (menuClosed)=\"onUserMenuClosed()\"\r\n [isShowSidebar]=\"isShowSidebar()\"\r\n (toggleMenuLock)=\"toggleMenuLock($event)\">\r\n </lib-layout-user>\r\n </div>\r\n\r\n <div class=\"c-vertical\"></div>\r\n </div>\r\n}\r\n", styles: ["::ng-deep .mat-mdc-tooltip-panel:has(.c-tooltip-menu-group-7a22ab15-0083-4d4c-9c0c-00a30bc8c140){pointer-events:none}:host ::ng-deep .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:16px!important}:host ::ng-deep .mat-nested-tree-node ul .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:32px!important}:host ::ng-deep .mat-nested-tree-node ul .mat-nested-tree-node ul .mat-nested-tree-node ul .c-menu-node-description-content{margin-left:48px!important}ul,li{margin-top:0;margin-bottom:0;list-style-type:none}.wrapper{display:flex;flex-direction:column;width:290px;background-color:#fff}.wrapper .c-header{display:flex;align-items:center;height:52px;padding:3px;gap:16px}.wrapper .c-header .c-logo{display:flex;justify-content:center;align-items:center;width:52px;height:52px}.wrapper .c-header .c-logo img{width:32px;height:32px;object-fit:cover}.wrapper .c-header .c-title-menu-group{display:flex;align-items:center;font-size:18px;font-weight:500;flex:1}.wrapper .c-body{flex:1;overflow-y:hidden}.wrapper .c-body .c-menu{height:100%;display:flex}.wrapper .c-body .c-menu .c-menu-group{display:flex;flex-direction:column;align-items:center;width:60px;overflow-y:scroll;scrollbar-width:none}.wrapper .c-body .c-menu .c-menu-group .c-menu-group-icon{display:flex;justify-content:center;align-items:center;min-height:50px;width:52px;border-radius:8px;transition:all .15s}.wrapper .c-body .c-menu .c-menu-group .c-menu-group-icon img{height:24px;width:24px;object-fit:contain}.wrapper .c-body .c-menu .c-menu-tree{flex:1;display:flex;flex-direction:column;padding:3px 4px 3px 3px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon{cursor:pointer;color:#757575;padding:0}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon.search{width:20px;height:20px;font-size:18px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-search .c-search-prefix-icon.cancel{width:16px;height:16px;font-size:16px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container{flex:1;overflow-y:scroll;scrollbar-width:none}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node{width:100%;display:flex;cursor:pointer;min-height:44px;padding:8px;border-radius:8px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-icon{display:flex;justify-content:center;align-items:center;height:100%}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description{flex:1;display:flex;align-items:center}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-content{flex:1;display:flex;align-items:center;flex-wrap:wrap;white-space:pre-wrap;font-size:15px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-icon-expand{display:flex;align-items:center;justify-content:start;background-color:transparent;border:none;font-size:20px}.wrapper .c-body .c-menu .c-menu-tree .c-menu-tree-container .c-menu-node .c-menu-node-description .c-menu-node-description-icon-pin{display:flex;align-items:center;justify-content:start;background-color:transparent;border:none;font-size:18px;opacity:0}.wrapper .c-footer{height:80px}.wrapper .c-vertical{position:fixed;height:100vh;left:58px;width:2px;background-color:#f8f9fa;pointer-events:none}\n"] }]
|
|
782
916
|
}], ctorParameters: () => [] });
|
|
783
917
|
|
|
784
918
|
class SidebarV1Component {
|
|
@@ -1187,6 +1321,15 @@ let HomePageComponent = class HomePageComponent {
|
|
|
1187
1321
|
// ==========================================
|
|
1188
1322
|
#layoutService = inject(SdLayoutService);
|
|
1189
1323
|
#i18n = inject(I18nService);
|
|
1324
|
+
// Map Language code → BCP 47 locale tag dùng cho Intl date formatting
|
|
1325
|
+
// WHY: must be declared before todayInfo — field init runs top-to-bottom; #getTodayInfo reads #localeMap.
|
|
1326
|
+
#localeMap = {
|
|
1327
|
+
vi: 'vi-VN',
|
|
1328
|
+
en: 'en-US',
|
|
1329
|
+
ja: 'ja-JP',
|
|
1330
|
+
ko: 'ko-KR',
|
|
1331
|
+
zh: 'zh-CN',
|
|
1332
|
+
};
|
|
1190
1333
|
// ==========================================
|
|
1191
1334
|
// SIGNALS (STATE)
|
|
1192
1335
|
// ==========================================
|
|
@@ -1206,14 +1349,6 @@ let HomePageComponent = class HomePageComponent {
|
|
|
1206
1349
|
// ==========================================
|
|
1207
1350
|
// PRIVATE METHODS
|
|
1208
1351
|
// ==========================================
|
|
1209
|
-
// Map Language code → BCP 47 locale tag dùng cho Intl date formatting
|
|
1210
|
-
#localeMap = {
|
|
1211
|
-
vi: 'vi-VN',
|
|
1212
|
-
en: 'en-US',
|
|
1213
|
-
ja: 'ja-JP',
|
|
1214
|
-
ko: 'ko-KR',
|
|
1215
|
-
zh: 'zh-CN',
|
|
1216
|
-
};
|
|
1217
1352
|
#getTimezone() {
|
|
1218
1353
|
const now = new Date();
|
|
1219
1354
|
const timezoneOffset = now.getTimezoneOffset();
|