cloud-ide-layout 1.0.62 → 1.0.64

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.
Files changed (13) hide show
  1. package/fesm2022/{cloud-ide-layout-cloud-ide-layout-CKLj-6xH.mjs → cloud-ide-layout-cloud-ide-layout-8S-2Ir2T.mjs} +186 -27
  2. package/fesm2022/cloud-ide-layout-cloud-ide-layout-8S-2Ir2T.mjs.map +1 -0
  3. package/fesm2022/{cloud-ide-layout-drawer-theme.component-DMn2Cznf.mjs → cloud-ide-layout-drawer-theme.component-j59G67L1.mjs} +2 -2
  4. package/fesm2022/{cloud-ide-layout-drawer-theme.component-DMn2Cznf.mjs.map → cloud-ide-layout-drawer-theme.component-j59G67L1.mjs.map} +1 -1
  5. package/fesm2022/{cloud-ide-layout-floating-entity-selection.component-L3hZ4LJm.mjs → cloud-ide-layout-floating-entity-selection.component-Bv5s966h.mjs} +2 -2
  6. package/fesm2022/{cloud-ide-layout-floating-entity-selection.component-L3hZ4LJm.mjs.map → cloud-ide-layout-floating-entity-selection.component-Bv5s966h.mjs.map} +1 -1
  7. package/fesm2022/{cloud-ide-layout-home-wrapper.component-ZWphfyNz.mjs → cloud-ide-layout-home-wrapper.component-CI7dPMxZ.mjs} +2 -2
  8. package/fesm2022/{cloud-ide-layout-home-wrapper.component-ZWphfyNz.mjs.map → cloud-ide-layout-home-wrapper.component-CI7dPMxZ.mjs.map} +1 -1
  9. package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-sYWI-yH9.mjs → cloud-ide-layout-sidedrawer-notes.component-Br9LCZ7q.mjs} +2 -2
  10. package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-sYWI-yH9.mjs.map → cloud-ide-layout-sidedrawer-notes.component-Br9LCZ7q.mjs.map} +1 -1
  11. package/fesm2022/cloud-ide-layout.mjs +1 -1
  12. package/package.json +1 -1
  13. package/fesm2022/cloud-ide-layout-cloud-ide-layout-CKLj-6xH.mjs.map +0 -1
@@ -1266,7 +1266,7 @@ class CideLytFloatingEntitySelectionService {
1266
1266
  }
1267
1267
  try {
1268
1268
  // Use relative import to avoid circular dependency
1269
- const module = await import('./cloud-ide-layout-floating-entity-selection.component-L3hZ4LJm.mjs');
1269
+ const module = await import('./cloud-ide-layout-floating-entity-selection.component-Bv5s966h.mjs');
1270
1270
  if (module.CideLytFloatingEntitySelectionComponent) {
1271
1271
  this.containerService.registerComponent('entity-selection-header', module.CideLytFloatingEntitySelectionComponent);
1272
1272
  console.log('✅ Entity selection component registered successfully');
@@ -1552,16 +1552,21 @@ class CideLytHeaderWrapperComponent {
1552
1552
  }
1553
1553
  /**
1554
1554
  * Load notifications from API
1555
+ * @param showReadOnly - If true, only load read notifications. If false, load all.
1555
1556
  */
1556
- loadNotifications() {
1557
+ loadNotifications(showReadOnly = false) {
1557
1558
  try {
1558
1559
  // Get notifications from WebSocket service (real-time)
1559
1560
  const wsNotifications = this.wsNotificationService?.allNotifications() || [];
1560
1561
  console.log('[Notifications] WebSocket notifications:', wsNotifications.length);
1561
1562
  // Load from API to get all notifications (including read status)
1562
- this.notificationApiService.getNotifications({
1563
+ // By default, we can filter to show unread first, but load all for "View All"
1564
+ const params = {
1563
1565
  pageSize: 20
1564
- }).subscribe({
1566
+ };
1567
+ // Optionally filter by status if we only want unread
1568
+ // Note: We load all and filter client-side for better UX
1569
+ this.notificationApiService.getNotifications(params).subscribe({
1565
1570
  next: (response) => {
1566
1571
  console.log('[Notifications] API response:', response);
1567
1572
  if (response && response.success && response.data) {
@@ -1631,8 +1636,11 @@ class CideLytHeaderWrapperComponent {
1631
1636
  updateNotificationDropdown() {
1632
1637
  const notifs = this.notifications();
1633
1638
  const unreadCount = this.unreadCount();
1634
- // Map notifications to dropdown items (show first 10)
1635
- this.notificationItems = notifs.slice(0, 10).map(notif => ({
1639
+ // Filter to show only unread notifications in the dropdown (or all if "View All" was clicked)
1640
+ // For now, show first 20 notifications (increased from 10 for better UX)
1641
+ const notificationsToShow = notifs.slice(0, 20);
1642
+ // Map notifications to dropdown items
1643
+ this.notificationItems = notificationsToShow.map(notif => ({
1636
1644
  id: notif.id,
1637
1645
  label: notif.title,
1638
1646
  icon: this.getNotificationIcon(notif.type),
@@ -1657,7 +1665,7 @@ class CideLytHeaderWrapperComponent {
1657
1665
  iconColor: 'tw-text-blue-500'
1658
1666
  });
1659
1667
  }
1660
- // Add "Clear All" option
1668
+ // Add "Clear All" option (only if there are notifications)
1661
1669
  this.notificationItems.push({
1662
1670
  id: 'clear-all',
1663
1671
  label: 'Clear All',
@@ -1672,10 +1680,13 @@ class CideLytHeaderWrapperComponent {
1672
1680
  label: '',
1673
1681
  divider: true
1674
1682
  });
1675
- // Add "View All" option
1683
+ // Add "View All" option (show count if more than displayed)
1684
+ const viewAllLabel = notifs.length > 20
1685
+ ? `View All Notifications (${notifs.length})`
1686
+ : 'View All Notifications';
1676
1687
  this.notificationItems.push({
1677
1688
  id: 'view-all',
1678
- label: 'View All Notifications',
1689
+ label: viewAllLabel,
1679
1690
  icon: 'list',
1680
1691
  iconColor: 'tw-text-blue-500'
1681
1692
  });
@@ -1716,6 +1727,54 @@ class CideLytHeaderWrapperComponent {
1716
1727
  };
1717
1728
  return colorMap[type] || 'tw-text-gray-500';
1718
1729
  }
1730
+ /**
1731
+ * Handle notification item click (from custom template)
1732
+ */
1733
+ onNotificationItemClick(notification) {
1734
+ // Mark notification as read when clicked
1735
+ this.markNotificationAsRead(String(notification.id));
1736
+ // Navigate to action URL if available
1737
+ if (notification?.action_url) {
1738
+ this.router.navigate([notification.action_url]);
1739
+ }
1740
+ }
1741
+ /**
1742
+ * Check if notification is read
1743
+ */
1744
+ isNotificationRead(notification) {
1745
+ return notification.isRead === true;
1746
+ }
1747
+ /**
1748
+ * Get time ago string
1749
+ */
1750
+ getTimeAgo(timestamp) {
1751
+ const now = new Date();
1752
+ const diff = now.getTime() - new Date(timestamp).getTime();
1753
+ const seconds = Math.floor(diff / 1000);
1754
+ const minutes = Math.floor(seconds / 60);
1755
+ const hours = Math.floor(minutes / 60);
1756
+ const days = Math.floor(hours / 24);
1757
+ if (days > 0)
1758
+ return `${days}d ago`;
1759
+ if (hours > 0)
1760
+ return `${hours}h ago`;
1761
+ if (minutes > 0)
1762
+ return `${minutes}m ago`;
1763
+ return 'Just now';
1764
+ }
1765
+ /**
1766
+ * Get notification icon color class
1767
+ */
1768
+ getNotificationIconColorClass(type) {
1769
+ const colorMap = {
1770
+ 'info': 'tw-text-blue-500',
1771
+ 'success': 'tw-text-green-500',
1772
+ 'warning': 'tw-text-yellow-500',
1773
+ 'error': 'tw-text-red-500',
1774
+ 'system': 'tw-text-gray-500'
1775
+ };
1776
+ return colorMap[type] || 'tw-text-gray-500';
1777
+ }
1719
1778
  /**
1720
1779
  * Handle notification dropdown item click
1721
1780
  */
@@ -1730,9 +1789,9 @@ class CideLytHeaderWrapperComponent {
1730
1789
  return;
1731
1790
  }
1732
1791
  if (item.id === 'view-all') {
1733
- // Navigate to notifications page or open full panel
1734
- console.log('View all notifications');
1735
- // TODO: Navigate to full notifications page
1792
+ // Show all notifications - for now, just reload with more items
1793
+ console.log('[Notifications] View all notifications');
1794
+ this.loadAllNotifications();
1736
1795
  return;
1737
1796
  }
1738
1797
  if (item.id === 'no-notifications' || item.id === 'divider' || item.id === 'divider-1' || item.id === 'divider-2') {
@@ -1750,19 +1809,28 @@ class CideLytHeaderWrapperComponent {
1750
1809
  * Mark a single notification as read
1751
1810
  */
1752
1811
  markNotificationAsRead(notificationId) {
1812
+ console.log('[Notifications] Marking as read:', notificationId);
1753
1813
  // Mark in WebSocket service
1754
1814
  if (this.wsNotificationService) {
1755
1815
  this.wsNotificationService.markAsRead(notificationId);
1756
1816
  }
1757
1817
  // Mark in API
1758
1818
  this.notificationApiService.markAsRead(notificationId).subscribe({
1759
- next: () => {
1760
- console.log('[Notifications] Marked as read:', notificationId);
1819
+ next: (response) => {
1820
+ console.log('[Notifications] Marked as read successfully:', response);
1761
1821
  // Reload notifications to update unread count
1762
1822
  this.loadNotifications();
1763
1823
  },
1764
1824
  error: (error) => {
1765
1825
  console.error('[Notifications] Error marking notification as read:', error);
1826
+ console.error('[Notifications] Error details:', {
1827
+ status: error?.status,
1828
+ statusText: error?.statusText,
1829
+ message: error?.message,
1830
+ url: error?.url
1831
+ });
1832
+ // Still reload to get updated state
1833
+ this.loadNotifications();
1766
1834
  }
1767
1835
  });
1768
1836
  }
@@ -1770,14 +1838,23 @@ class CideLytHeaderWrapperComponent {
1770
1838
  * Mark all notifications as read
1771
1839
  */
1772
1840
  markAllAsRead() {
1841
+ console.log('[Notifications] Marking all as read');
1773
1842
  this.notificationApiService.markAllAsRead().subscribe({
1774
- next: () => {
1775
- console.log('[Notifications] All notifications marked as read');
1843
+ next: (response) => {
1844
+ console.log('[Notifications] All notifications marked as read successfully:', response);
1776
1845
  // Reload notifications to update unread count
1777
1846
  this.loadNotifications();
1778
1847
  },
1779
1848
  error: (error) => {
1780
1849
  console.error('[Notifications] Error marking all as read:', error);
1850
+ console.error('[Notifications] Error details:', {
1851
+ status: error?.status,
1852
+ statusText: error?.statusText,
1853
+ message: error?.message,
1854
+ url: error?.url
1855
+ });
1856
+ // Still reload to get updated state
1857
+ this.loadNotifications();
1781
1858
  }
1782
1859
  });
1783
1860
  }
@@ -1786,22 +1863,104 @@ class CideLytHeaderWrapperComponent {
1786
1863
  */
1787
1864
  clearAllNotifications() {
1788
1865
  if (confirm('Are you sure you want to clear all notifications? This will mark them all as read.')) {
1866
+ console.log('[Notifications] Clearing all notifications');
1789
1867
  // First mark all as read
1790
1868
  this.notificationApiService.markAllAsRead().subscribe({
1791
- next: () => {
1792
- console.log('[Notifications] All notifications cleared');
1793
- // Clear local notifications array
1869
+ next: (response) => {
1870
+ console.log('[Notifications] All notifications marked as read:', response);
1871
+ // Filter current notifications to mark them as read locally
1872
+ const currentNotifs = this.notifications();
1873
+ const updatedNotifs = currentNotifs.map(notif => ({
1874
+ ...notif,
1875
+ isRead: true
1876
+ }));
1877
+ // Clear notifications from view (they're all read now)
1794
1878
  this.notifications.set([]);
1795
1879
  this.updateNotificationDropdown();
1796
- // Reload to get updated state
1797
- this.loadNotifications();
1880
+ // Reload after a short delay to get updated state from server
1881
+ // This will show empty or only new unread notifications
1882
+ setTimeout(() => {
1883
+ this.loadNotifications();
1884
+ }, 500);
1798
1885
  },
1799
1886
  error: (error) => {
1800
1887
  console.error('[Notifications] Error clearing all notifications:', error);
1888
+ console.error('[Notifications] Error details:', {
1889
+ status: error?.status,
1890
+ statusText: error?.statusText,
1891
+ message: error?.message,
1892
+ url: error?.url
1893
+ });
1894
+ // Still try to reload
1895
+ this.loadNotifications();
1801
1896
  }
1802
1897
  });
1803
1898
  }
1804
1899
  }
1900
+ /**
1901
+ * Load all notifications (for "View All" functionality)
1902
+ */
1903
+ loadAllNotifications() {
1904
+ try {
1905
+ const wsNotifications = this.wsNotificationService?.allNotifications() || [];
1906
+ console.log('[Notifications] Loading all notifications (View All)');
1907
+ // Load more notifications from API (increase pageSize)
1908
+ this.notificationApiService.getNotifications({
1909
+ pageSize: 100 // Load more for "View All"
1910
+ }).subscribe({
1911
+ next: (response) => {
1912
+ console.log('[Notifications] All notifications API response:', response);
1913
+ if (response && response.success && response.data) {
1914
+ // Convert server notifications to notification payloads
1915
+ const apiPayloads = response.data.map((notif) => ({
1916
+ id: String(notif._id),
1917
+ type: notif.not_type || 'info',
1918
+ category: notif.not_category,
1919
+ title: notif.not_title,
1920
+ message: notif.not_message,
1921
+ data: notif.not_data,
1922
+ action_url: notif.not_action_url,
1923
+ action_label: notif.not_action_label,
1924
+ priority: notif.not_priority || 'normal',
1925
+ created_at: new Date(notif.not_created_at),
1926
+ timestamp: new Date(notif.not_created_at),
1927
+ isRead: notif.not_status === 'read' || notif.not_read_at !== undefined
1928
+ }));
1929
+ // Merge WebSocket and API notifications
1930
+ const mergedNotifications = [];
1931
+ // Add API notifications first
1932
+ apiPayloads.forEach(apiNotif => {
1933
+ mergedNotifications.push(apiNotif);
1934
+ });
1935
+ // Add WebSocket notifications that aren't in API
1936
+ wsNotifications.forEach(wsNotif => {
1937
+ if (!mergedNotifications.find(n => n.id === wsNotif.id)) {
1938
+ mergedNotifications.push({ ...wsNotif, isRead: false });
1939
+ }
1940
+ });
1941
+ // Sort by timestamp (newest first)
1942
+ mergedNotifications.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
1943
+ console.log('[Notifications] Total notifications loaded:', mergedNotifications.length);
1944
+ this.notifications.set(mergedNotifications);
1945
+ this.updateNotificationDropdown();
1946
+ }
1947
+ else {
1948
+ console.warn('[Notifications] API response invalid');
1949
+ this.notifications.set(wsNotifications);
1950
+ this.updateNotificationDropdown();
1951
+ }
1952
+ },
1953
+ error: (error) => {
1954
+ console.error('[Notifications] Error loading all notifications:', error);
1955
+ this.notifications.set(wsNotifications);
1956
+ this.updateNotificationDropdown();
1957
+ }
1958
+ });
1959
+ }
1960
+ catch (error) {
1961
+ console.error('[Notifications] Error in loadAllNotifications:', error);
1962
+ }
1963
+ }
1805
1964
  ngAfterViewInit() {
1806
1965
  // No need to manually load file details - cideEleFileImage directive will handle it
1807
1966
  }
@@ -2186,12 +2345,12 @@ class CideLytHeaderWrapperComponent {
2186
2345
  }
2187
2346
  }
2188
2347
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytHeaderWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2189
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideLytHeaderWrapperComponent, isStandalone: true, selector: "cide-lyt-header-wrapper", viewQueries: [{ propertyName: "triggerTemplate", first: true, predicate: ["triggerTemplate"], descendants: true }, { propertyName: "financialYearTriggerTemplate", first: true, predicate: ["financialYearTriggerTemplate"], descendants: true }, { propertyName: "academicYearTriggerTemplate", first: true, predicate: ["academicYearTriggerTemplate"], descendants: true }, { propertyName: "notificationTriggerTemplate", first: true, predicate: ["notificationTriggerTemplate"], descendants: true }], ngImport: i0, template: "<header id=\"cide-lyt-header-wrapper\" class=\"cide-lyt-header tw-w-full tw-select-none cide-lyt-header-wrapper-hide\">\n <!-- Logo Section -->\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <div class=\"header-logo-container tw-flex tw-items-center tw-gap-3 tw-cursor-pointer\" (click)=\"onLogoClick()\"\n (keydown.enter)=\"onLogoClick()\" (keydown.space)=\"onLogoClick()\" tabindex=\"0\" role=\"button\"\n aria-label=\"Navigate to home\" title=\"Click to go to control panel home\">\n @if (appStateService.activeEntity()?.syen_photo_id_cyfm) {\n <img cideEleFileImage [fileId]=\"(appStateService.activeEntity()?.syen_photo_id_cyfm || '')\"\n [altText]=\"'Entity Logo'\" class=\"tw-w-8 tw-h-8 tw-object-contain\">\n } @else {\n <cide-ele-icon name=\"business\" class=\"tw-w-8 tw-h-8 tw-text-blue-600\"></cide-ele-icon>\n }\n\n </div>\n @if (appStateService.activeEntity()?.syen_name) {\n <span\n class=\"tw-text-md tw-font-semibold tw-text-blue-600 hover:tw-text-blue-800 tw-cursor-pointer sm:block tw-transition-colors tw-duration-200 hover:tw-underline\"\n (click)=\"onEntityNameClick()\" title=\"Click to switch entity\">\n {{ appStateService.activeEntity()?.syen_name }}\n </span>\n }\n </div>\n <!-- Search Section -->\n <div class=\"header-search-container\">\n <cide-ele-input id=\"cide_lyt_header_search\" placeholder=\"Search...\" leadingIcon=\"search\"\n size=\"md\"></cide-ele-input>\n </div>\n\n <!-- Icons Section -->\n <div class=\"header-icons-container\">\n <!-- Financial Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"financialYearItems\" [config]=\"financialYearConfig\"\n [triggerTemplate]=\"financialYearTriggerTemplate\"\n (itemClick)=\"onFinancialYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Financial Year</div>\n </div>\n \n <ng-template #financialYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">calendar_today</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentFinancialYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Academic Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"academicYearItems\" [config]=\"academicYearConfig\"\n [triggerTemplate]=\"academicYearTriggerTemplate\"\n (itemClick)=\"onAcademicYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Academic Year</div>\n </div>\n \n <ng-template #academicYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">school</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentAcademicYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Notifications Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown \n [items]=\"notificationItems\" \n [config]=\"notificationConfig\"\n [triggerTemplate]=\"notificationTriggerTemplate\"\n (itemClick)=\"onNotificationClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Notifications</div>\n </div>\n \n <ng-template #notificationTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-icon notification-icon\" [class.active]=\"isOpen\">\n <cide-ele-icon>notifications</cide-ele-icon>\n @if (unreadCount() > 0) {\n <div class=\"header-badge\">{{ unreadCount() > 99 ? '99+' : unreadCount() }}</div>\n }\n </div>\n </ng-template>\n\n <div class=\"header-divider\"></div>\n\n <!-- Profile with Dropdown -->\n <div class=\"header-icon user-profile\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"profileItems\" [config]=\"profileConfig\"\n [triggerTemplate]=\"triggerTemplate\"\n (itemClick)=\"onProfileClick($event)\">\n <ng-template #triggerTemplate>\n @if (appStateService.currentUser()?.user_photo_id_cyfm) {\n <div class=\"profile-avatar\">\n <img cideEleFileImage [fileId]=\"(appStateService.currentUser()?.user_photo_id_cyfm || '')\"\n [altText]=\"'User Profile Photo'\" class=\"tw-w-full tw-h-full tw-object-cover tw-rounded-full\">\n </div>\n } @else {\n <div class=\"profile-avatar\">\n <cide-ele-icon name=\"person\" class=\"tw-w-6 tw-h-6 tw-text-white\"></cide-ele-icon>\n </div>\n }\n </ng-template>\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">My Account</div>\n </div>\n </div>\n</header>", styles: [".cide-lyt-header{display:flex;align-items:center;justify-content:space-between;background:linear-gradient(to right,#fffffff2,#f9fafbf2);box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:20;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgba(229,231,235,.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-logo-container{height:100%;display:flex;align-items:center;padding:.5rem 0;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);border-radius:8px;outline:none}.header-logo-container img{height:30px;max-height:100%;transition:all .3s ease;border-radius:5px;overflow:hidden;box-shadow:0 1px 4px #0000000d}.header-logo-container:hover img{transform:scale(1.03);filter:brightness(1.05);box-shadow:0 2px 6px #00000014}.header-logo-container:after{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:linear-gradient(to bottom right,#fff0,#ffffff4d,#fff0);transform:rotate(30deg);opacity:0;transition:transform .6s ease,opacity .6s ease;pointer-events:none}.header-logo-container:hover:after,.header-logo-container:focus:after{opacity:1;transform:rotate(30deg) translate(50%,50%)}.header-search-container{flex-grow:1;max-width:600px;margin:0 2rem;position:relative;transition:all .3s ease}::ng-deep .header-search-container #cide_lyt_header_search{width:100%;background-color:#f9fafbcc;border-radius:20px!important;transition:all .3s ease;overflow:visible;transform:translateZ(0)}::ng-deep .header-search-container #cide_lyt_header_search:hover{box-shadow:0 3px 12px #00000014;background-color:#fff;transform:translateY(-1px)}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-input{background-color:transparent;font-size:.85rem!important;letter-spacing:.01em}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:#6b7280b3!important;font-size:1.1rem!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within{transform:translateY(-1px) scale(1.01)}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-input{border-color:#3b82f6!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-leading-icon{color:#3b82f6!important}.header-icons-container{display:flex;align-items:center;gap:1rem}.header-icon{position:relative;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-dropdown-container{position:relative;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-icon:before{content:\"\";position:absolute;inset:0;background-color:#3b82f61a;border-radius:.5rem;opacity:0;transform:scale(.8);transition:all .2s cubic-bezier(.4,0,.2,1)}.header-icon:hover:before{opacity:1;transform:scale(1)}.header-icon:hover{color:#3b82f6}.header-icon:active{transform:scale(.95)}.header-tooltip{position:absolute;bottom:-26px;left:50%;transform:translate(-50%);background-color:#374151e6;color:#fff;padding:.25rem .6rem;border-radius:.25rem;font-size:.7rem;white-space:nowrap;opacity:0;pointer-events:none;transition:all .2s cubic-bezier(.4,0,.2,1);z-index:1000;box-shadow:0 2px 5px #0003;letter-spacing:.01em;will-change:transform,opacity}.header-tooltip:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:5px;border-style:solid;border-color:transparent transparent rgba(55,65,81,.9) transparent}.header-icon:hover .header-tooltip{opacity:1;transform:translate(-50%) translateY(0)}.header-badge{position:absolute;top:0;right:0;min-width:16px;height:16px;border-radius:8px;background-color:#ef4444;color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 1px 3px #ef44444d;font-weight:600;z-index:2;transition:all .2s ease}.header-icon:hover .header-badge{transform:scale(1.1)}.header-divider{height:20px;width:1px;background-color:#e5e7ebcc;margin:0 6px}.header-year-dropdown-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.header-year-pill{position:relative;display:flex;align-items:center;padding:.25rem .625rem;background:linear-gradient(135deg,#3b82f61a,#2563eb26);border:1px solid rgba(59,130,246,.3);border-radius:9999px;color:#2563eb;font-size:.6875rem;font-weight:600;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;white-space:nowrap;box-shadow:0 1px 2px #3b82f61a;min-height:22px;height:22px;line-height:1}.header-year-pill:hover{background:linear-gradient(135deg,#3b82f626,#2563eb33);border-color:#3b82f666;transform:translateY(-1px);box-shadow:0 2px 6px #3b82f626}.header-year-pill-text{max-width:180px;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em;line-height:1;display:inline-block}::ng-deep .header-dropdown-container .dropdown-trigger{background:transparent!important;border:none!important;border-radius:0!important;padding:0!important;width:100%!important;height:100%!important;min-width:auto!important;box-shadow:none!important;display:flex!important;align-items:center!important;justify-content:center!important;transition:none!important;cursor:pointer!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover{background:transparent!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover .header-year-pill{background:linear-gradient(135deg,#3b82f626,#2563eb33)!important;border-color:#3b82f666!important;transform:translateY(-1px)!important;box-shadow:0 2px 6px #3b82f626!important}::ng-deep .header-dropdown-container .dropdown-trigger:focus,::ng-deep .header-dropdown-container .dropdown-trigger:focus-visible,::ng-deep .header-dropdown-container .dropdown-trigger:active{outline:none!important;box-shadow:0 2px 6px #3b82f626!important}.profile-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;font-size:.75rem;font-weight:600;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #2563eb33;transition:all .2s cubic-bezier(.4,0,.2,1);letter-spacing:-.5px;cursor:pointer;border:2px solid transparent}.profile-avatar:hover,.header-icon:hover .profile-avatar{transform:scale(1.08);box-shadow:0 3px 8px #2563eb4d;border-color:#3b82f64d}::ng-deep .user-profile .dropdown-trigger{background:transparent!important;border:none!important;padding:0!important;width:auto!important;height:auto!important;border-radius:0!important}::ng-deep .user-profile .dropdown-trigger:hover{background:transparent!important}::ng-deep .user-profile .dropdown-trigger:focus,::ng-deep .user-profile .dropdown-trigger:focus-visible,::ng-deep .user-profile .dropdown-trigger:active{outline:none!important;box-shadow:none!important}.header-avatar{width:36px;height:36px;border-radius:50%;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);border:2px solid transparent;box-shadow:0 2px 4px #0000001a}.header-avatar:hover{border-color:#3b82f6;transform:scale(1.05);box-shadow:0 3px 6px #3b82f64d}@media (max-width: 768px){.header-search-container{margin:0 1rem}.header-icons-container{gap:.5rem}}@media (max-width: 640px){.header-search-container{max-width:200px;margin:0 .5rem}}\n"], dependencies: [{ kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "size"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleDropdownComponent, selector: "cide-ele-dropdown", inputs: ["items", "config", "triggerTemplate", "menuTemplate"], outputs: ["itemClick", "dropdownToggle"] }, { kind: "directive", type: CideEleFileImageDirective, selector: "[cideEleFileImage]", inputs: ["fileId", "altText"] }] });
2348
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideLytHeaderWrapperComponent, isStandalone: true, selector: "cide-lyt-header-wrapper", viewQueries: [{ propertyName: "triggerTemplate", first: true, predicate: ["triggerTemplate"], descendants: true }, { propertyName: "financialYearTriggerTemplate", first: true, predicate: ["financialYearTriggerTemplate"], descendants: true }, { propertyName: "academicYearTriggerTemplate", first: true, predicate: ["academicYearTriggerTemplate"], descendants: true }, { propertyName: "notificationTriggerTemplate", first: true, predicate: ["notificationTriggerTemplate"], descendants: true }], ngImport: i0, template: "<header id=\"cide-lyt-header-wrapper\" class=\"cide-lyt-header tw-w-full tw-select-none cide-lyt-header-wrapper-hide\">\n <!-- Logo Section -->\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <div class=\"header-logo-container tw-flex tw-items-center tw-gap-3 tw-cursor-pointer\" (click)=\"onLogoClick()\"\n (keydown.enter)=\"onLogoClick()\" (keydown.space)=\"onLogoClick()\" tabindex=\"0\" role=\"button\"\n aria-label=\"Navigate to home\" title=\"Click to go to control panel home\">\n @if (appStateService.activeEntity()?.syen_photo_id_cyfm) {\n <img cideEleFileImage [fileId]=\"(appStateService.activeEntity()?.syen_photo_id_cyfm || '')\"\n [altText]=\"'Entity Logo'\" class=\"tw-w-8 tw-h-8 tw-object-contain\">\n } @else {\n <cide-ele-icon name=\"business\" class=\"tw-w-8 tw-h-8 tw-text-blue-600\"></cide-ele-icon>\n }\n\n </div>\n @if (appStateService.activeEntity()?.syen_name) {\n <span\n class=\"tw-text-md tw-font-semibold tw-text-blue-600 hover:tw-text-blue-800 tw-cursor-pointer sm:block tw-transition-colors tw-duration-200 hover:tw-underline\"\n (click)=\"onEntityNameClick()\" title=\"Click to switch entity\">\n {{ appStateService.activeEntity()?.syen_name }}\n </span>\n }\n </div>\n <!-- Search Section -->\n <div class=\"header-search-container\">\n <cide-ele-input id=\"cide_lyt_header_search\" placeholder=\"Search...\" leadingIcon=\"search\"\n size=\"md\"></cide-ele-input>\n </div>\n\n <!-- Icons Section -->\n <div class=\"header-icons-container\">\n <!-- Financial Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"financialYearItems\" [config]=\"financialYearConfig\"\n [triggerTemplate]=\"financialYearTriggerTemplate\"\n (itemClick)=\"onFinancialYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Financial Year</div>\n </div>\n \n <ng-template #financialYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">calendar_today</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentFinancialYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Academic Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"academicYearItems\" [config]=\"academicYearConfig\"\n [triggerTemplate]=\"academicYearTriggerTemplate\"\n (itemClick)=\"onAcademicYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Academic Year</div>\n </div>\n \n <ng-template #academicYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">school</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentAcademicYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Notifications Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown \n [items]=\"notificationItems\" \n [config]=\"notificationConfig\"\n [triggerTemplate]=\"notificationTriggerTemplate\"\n [menuTemplate]=\"notificationMenuTemplate\"\n (itemClick)=\"onNotificationClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Notifications</div>\n </div>\n \n <ng-template #notificationTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-icon notification-icon\" [class.active]=\"isOpen\">\n <cide-ele-icon>notifications</cide-ele-icon>\n @if (unreadCount() > 0) {\n <div class=\"header-badge\">{{ unreadCount() > 99 ? '99+' : unreadCount() }}</div>\n }\n </div>\n </ng-template>\n\n <!-- Custom Notification Menu Template -->\n <ng-template #notificationMenuTemplate let-items=\"items\">\n <div class=\"notification-dropdown-menu\">\n <!-- Header -->\n <div class=\"notification-dropdown-header\">\n <h3 class=\"notification-dropdown-title\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"notification-unread-badge\">{{ unreadCount() }} unread</span>\n }\n </div>\n\n <!-- Notifications List -->\n <div class=\"notification-dropdown-body\">\n @if (notifications().length === 0) {\n <div class=\"notification-empty-state\">\n <cide-ele-icon class=\"notification-empty-icon\">notifications_off</cide-ele-icon>\n <p class=\"notification-empty-text\">No notifications</p>\n </div>\n } @else {\n @for (notif of notifications().slice(0, 10); track notif.id) {\n <div \n class=\"notification-item\" \n [class.unread]=\"!isNotificationRead(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <div class=\"notification-item-icon\">\n <cide-ele-icon [class]=\"getNotificationIconColorClass(notif.type)\">\n {{ getNotificationIcon(notif.type) }}\n </cide-ele-icon>\n </div>\n <div class=\"notification-item-content\">\n <div class=\"notification-item-header\">\n <h4 class=\"notification-item-title\">{{ notif.title }}</h4>\n <span class=\"notification-item-time\">{{ getTimeAgo(notif.timestamp) }}</span>\n </div>\n <p class=\"notification-item-message\">{{ notif.message }}</p>\n @if (notif.priority === 'urgent') {\n <span class=\"notification-priority-badge urgent\">Urgent</span>\n }\n </div>\n @if (!isNotificationRead(notif)) {\n <div class=\"notification-unread-indicator\"></div>\n }\n </div>\n }\n }\n </div>\n\n <!-- Footer Actions -->\n @if (notifications().length > 0) {\n <div class=\"notification-dropdown-footer\">\n <div class=\"notification-actions\">\n @if (unreadCount() > 0) {\n <button \n type=\"button\" \n class=\"notification-action-btn\"\n (click)=\"markAllAsRead()\">\n <cide-ele-icon>done_all</cide-ele-icon>\n <span>Mark all read</span>\n </button>\n }\n <button \n type=\"button\" \n class=\"notification-action-btn\"\n (click)=\"clearAllNotifications()\">\n <cide-ele-icon>clear_all</cide-ele-icon>\n <span>Clear all</span>\n </button>\n <button \n type=\"button\" \n class=\"notification-action-btn primary\"\n (click)=\"loadAllNotifications()\">\n <cide-ele-icon>list</cide-ele-icon>\n <span>View all</span>\n </button>\n </div>\n </div>\n }\n </div>\n </ng-template>\n\n <div class=\"header-divider\"></div>\n\n <!-- Profile with Dropdown -->\n <div class=\"header-icon user-profile\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"profileItems\" [config]=\"profileConfig\"\n [triggerTemplate]=\"triggerTemplate\"\n (itemClick)=\"onProfileClick($event)\">\n <ng-template #triggerTemplate>\n @if (appStateService.currentUser()?.user_photo_id_cyfm) {\n <div class=\"profile-avatar\">\n <img cideEleFileImage [fileId]=\"(appStateService.currentUser()?.user_photo_id_cyfm || '')\"\n [altText]=\"'User Profile Photo'\" class=\"tw-w-full tw-h-full tw-object-cover tw-rounded-full\">\n </div>\n } @else {\n <div class=\"profile-avatar\">\n <cide-ele-icon name=\"person\" class=\"tw-w-6 tw-h-6 tw-text-white\"></cide-ele-icon>\n </div>\n }\n </ng-template>\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">My Account</div>\n </div>\n </div>\n</header>", styles: [".cide-lyt-header{display:flex;align-items:center;justify-content:space-between;background:linear-gradient(to right,#fffffff2,#f9fafbf2);box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:20;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgba(229,231,235,.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-logo-container{height:100%;display:flex;align-items:center;padding:.5rem 0;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);border-radius:8px;outline:none}.header-logo-container img{height:30px;max-height:100%;transition:all .3s ease;border-radius:5px;overflow:hidden;box-shadow:0 1px 4px #0000000d}.header-logo-container:hover img{transform:scale(1.03);filter:brightness(1.05);box-shadow:0 2px 6px #00000014}.header-logo-container:after{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:linear-gradient(to bottom right,#fff0,#ffffff4d,#fff0);transform:rotate(30deg);opacity:0;transition:transform .6s ease,opacity .6s ease;pointer-events:none}.header-logo-container:hover:after,.header-logo-container:focus:after{opacity:1;transform:rotate(30deg) translate(50%,50%)}.header-search-container{flex-grow:1;max-width:600px;margin:0 2rem;position:relative;transition:all .3s ease}::ng-deep .header-search-container #cide_lyt_header_search{width:100%;background-color:#f9fafbcc;border-radius:20px!important;transition:all .3s ease;overflow:visible;transform:translateZ(0)}::ng-deep .header-search-container #cide_lyt_header_search:hover{box-shadow:0 3px 12px #00000014;background-color:#fff;transform:translateY(-1px)}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-input{background-color:transparent;font-size:.85rem!important;letter-spacing:.01em}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:#6b7280b3!important;font-size:1.1rem!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within{transform:translateY(-1px) scale(1.01)}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-input{border-color:#3b82f6!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-leading-icon{color:#3b82f6!important}.header-icons-container{display:flex;align-items:center;gap:1rem}.header-icon{position:relative;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-dropdown-container{position:relative;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-icon:before{content:\"\";position:absolute;inset:0;background-color:#3b82f61a;border-radius:.5rem;opacity:0;transform:scale(.8);transition:all .2s cubic-bezier(.4,0,.2,1)}.header-icon:hover:before{opacity:1;transform:scale(1)}.header-icon:hover{color:#3b82f6}.header-icon:active{transform:scale(.95)}.header-tooltip{position:absolute;bottom:-26px;left:50%;transform:translate(-50%);background-color:#374151e6;color:#fff;padding:.25rem .6rem;border-radius:.25rem;font-size:.7rem;white-space:nowrap;opacity:0;pointer-events:none;transition:all .2s cubic-bezier(.4,0,.2,1);z-index:1000;box-shadow:0 2px 5px #0003;letter-spacing:.01em;will-change:transform,opacity}.header-tooltip:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:5px;border-style:solid;border-color:transparent transparent rgba(55,65,81,.9) transparent}.header-icon:hover .header-tooltip{opacity:1;transform:translate(-50%) translateY(0)}.header-badge{position:absolute;top:0;right:0;min-width:16px;height:16px;border-radius:8px;background-color:#ef4444;color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 1px 3px #ef44444d;font-weight:600;z-index:2;transition:all .2s ease}.header-icon:hover .header-badge{transform:scale(1.1)}.header-divider{height:20px;width:1px;background-color:#e5e7ebcc;margin:0 6px}.header-year-dropdown-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.header-year-pill{position:relative;display:flex;align-items:center;padding:.25rem .625rem;background:linear-gradient(135deg,#3b82f61a,#2563eb26);border:1px solid rgba(59,130,246,.3);border-radius:9999px;color:#2563eb;font-size:.6875rem;font-weight:600;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;white-space:nowrap;box-shadow:0 1px 2px #3b82f61a;min-height:22px;height:22px;line-height:1}.header-year-pill:hover{background:linear-gradient(135deg,#3b82f626,#2563eb33);border-color:#3b82f666;transform:translateY(-1px);box-shadow:0 2px 6px #3b82f626}.header-year-pill-text{max-width:180px;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em;line-height:1;display:inline-block}::ng-deep .header-dropdown-container .dropdown-trigger{background:transparent!important;border:none!important;border-radius:0!important;padding:0!important;width:100%!important;height:100%!important;min-width:auto!important;box-shadow:none!important;display:flex!important;align-items:center!important;justify-content:center!important;transition:none!important;cursor:pointer!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover{background:transparent!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover .header-year-pill{background:linear-gradient(135deg,#3b82f626,#2563eb33)!important;border-color:#3b82f666!important;transform:translateY(-1px)!important;box-shadow:0 2px 6px #3b82f626!important}::ng-deep .header-dropdown-container .dropdown-trigger:focus,::ng-deep .header-dropdown-container .dropdown-trigger:focus-visible,::ng-deep .header-dropdown-container .dropdown-trigger:active{outline:none!important;box-shadow:0 2px 6px #3b82f626!important}.profile-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;font-size:.75rem;font-weight:600;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #2563eb33;transition:all .2s cubic-bezier(.4,0,.2,1);letter-spacing:-.5px;cursor:pointer;border:2px solid transparent}.profile-avatar:hover,.header-icon:hover .profile-avatar{transform:scale(1.08);box-shadow:0 3px 8px #2563eb4d;border-color:#3b82f64d}::ng-deep .user-profile .dropdown-trigger{background:transparent!important;border:none!important;padding:0!important;width:auto!important;height:auto!important;border-radius:0!important}::ng-deep .user-profile .dropdown-trigger:hover{background:transparent!important}::ng-deep .user-profile .dropdown-trigger:focus,::ng-deep .user-profile .dropdown-trigger:focus-visible,::ng-deep .user-profile .dropdown-trigger:active{outline:none!important;box-shadow:none!important}.header-avatar{width:36px;height:36px;border-radius:50%;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);border:2px solid transparent;box-shadow:0 2px 4px #0000001a}.header-avatar:hover{border-color:#3b82f6;transform:scale(1.05);box-shadow:0 3px 6px #3b82f64d}@media (max-width: 768px){.header-search-container{margin:0 1rem}.header-icons-container{gap:.5rem}}@media (max-width: 640px){.header-search-container{max-width:200px;margin:0 .5rem}}.notification-dropdown-menu{width:100%;max-width:400px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;overflow:hidden;display:flex;flex-direction:column;max-height:600px}.notification-dropdown-header{padding:16px 20px;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid rgba(255,255,255,.1)}.notification-dropdown-title{margin:0;font-size:1.1rem;font-weight:600;letter-spacing:-.01em}.notification-unread-badge{background:#ffffff40;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);padding:4px 12px;border-radius:12px;font-size:.75rem;font-weight:600;border:1px solid rgba(255,255,255,.3)}.notification-dropdown-body{flex:1;overflow-y:auto;max-height:450px;padding:8px 0}.notification-dropdown-body::-webkit-scrollbar{width:6px}.notification-dropdown-body::-webkit-scrollbar-track{background:#f1f1f1}.notification-dropdown-body::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.notification-dropdown-body::-webkit-scrollbar-thumb:hover{background:#a8a8a8}.notification-empty-state{padding:40px 20px;text-align:center;color:#9ca3af}.notification-empty-icon{font-size:3rem!important;color:#d1d5db!important;margin-bottom:12px}.notification-empty-text{margin:0;font-size:.9rem;color:#6b7280}.notification-item{display:flex;align-items:flex-start;padding:12px 20px;cursor:pointer;transition:all .2s ease;border-left:3px solid transparent;position:relative;gap:12px}.notification-item:hover{background:#f9fafb;border-left-color:#3b82f6}.notification-item.unread{background:#eff6ff;border-left-color:#3b82f6}.notification-item.unread:hover{background:#dbeafe}.notification-item-icon{flex-shrink:0;width:40px;height:40px;border-radius:10px;background:#f3f4f6;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.notification-item.unread .notification-item-icon{background:#dbeafe}.notification-item-icon cide-ele-icon{font-size:1.25rem!important}.notification-item-content{flex:1;min-width:0}.notification-item-header{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:4px}.notification-item-title{margin:0;font-size:.9rem;font-weight:600;color:#111827;line-height:1.4;flex:1}.notification-item-time{font-size:.75rem;color:#6b7280;white-space:nowrap;flex-shrink:0}.notification-item-message{margin:0;font-size:.85rem;color:#4b5563;line-height:1.5;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.notification-priority-badge{display:inline-block;margin-top:6px;padding:2px 8px;border-radius:4px;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.notification-priority-badge.urgent{background:#fee2e2;color:#dc2626}.notification-unread-indicator{position:absolute;top:16px;right:16px;width:8px;height:8px;border-radius:50%;background:#3b82f6;box-shadow:0 0 0 2px #fff}.notification-dropdown-footer{padding:12px 20px;background:#f9fafb;border-top:1px solid #e5e7eb}.notification-actions{display:flex;gap:8px;justify-content:flex-end}.notification-action-btn{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #e5e7eb;background:#fff;border-radius:6px;font-size:.8rem;color:#4b5563;cursor:pointer;transition:all .2s ease;font-weight:500}.notification-action-btn:hover{background:#f3f4f6;border-color:#d1d5db;color:#111827}.notification-action-btn.primary{background:#3b82f6;color:#fff;border-color:#3b82f6}.notification-action-btn.primary:hover{background:#2563eb;border-color:#2563eb}.notification-action-btn cide-ele-icon{font-size:1rem!important}\n"], dependencies: [{ kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "size"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleDropdownComponent, selector: "cide-ele-dropdown", inputs: ["items", "config", "triggerTemplate", "menuTemplate"], outputs: ["itemClick", "dropdownToggle"] }, { kind: "directive", type: CideEleFileImageDirective, selector: "[cideEleFileImage]", inputs: ["fileId", "altText"] }] });
2190
2349
  }
2191
2350
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytHeaderWrapperComponent, decorators: [{
2192
2351
  type: Component,
2193
2352
  args: [{ selector: 'cide-lyt-header-wrapper', imports: [CideInputComponent, CommonModule, CideIconComponent,
2194
- CideEleDropdownComponent, CideEleFileImageDirective], template: "<header id=\"cide-lyt-header-wrapper\" class=\"cide-lyt-header tw-w-full tw-select-none cide-lyt-header-wrapper-hide\">\n <!-- Logo Section -->\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <div class=\"header-logo-container tw-flex tw-items-center tw-gap-3 tw-cursor-pointer\" (click)=\"onLogoClick()\"\n (keydown.enter)=\"onLogoClick()\" (keydown.space)=\"onLogoClick()\" tabindex=\"0\" role=\"button\"\n aria-label=\"Navigate to home\" title=\"Click to go to control panel home\">\n @if (appStateService.activeEntity()?.syen_photo_id_cyfm) {\n <img cideEleFileImage [fileId]=\"(appStateService.activeEntity()?.syen_photo_id_cyfm || '')\"\n [altText]=\"'Entity Logo'\" class=\"tw-w-8 tw-h-8 tw-object-contain\">\n } @else {\n <cide-ele-icon name=\"business\" class=\"tw-w-8 tw-h-8 tw-text-blue-600\"></cide-ele-icon>\n }\n\n </div>\n @if (appStateService.activeEntity()?.syen_name) {\n <span\n class=\"tw-text-md tw-font-semibold tw-text-blue-600 hover:tw-text-blue-800 tw-cursor-pointer sm:block tw-transition-colors tw-duration-200 hover:tw-underline\"\n (click)=\"onEntityNameClick()\" title=\"Click to switch entity\">\n {{ appStateService.activeEntity()?.syen_name }}\n </span>\n }\n </div>\n <!-- Search Section -->\n <div class=\"header-search-container\">\n <cide-ele-input id=\"cide_lyt_header_search\" placeholder=\"Search...\" leadingIcon=\"search\"\n size=\"md\"></cide-ele-input>\n </div>\n\n <!-- Icons Section -->\n <div class=\"header-icons-container\">\n <!-- Financial Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"financialYearItems\" [config]=\"financialYearConfig\"\n [triggerTemplate]=\"financialYearTriggerTemplate\"\n (itemClick)=\"onFinancialYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Financial Year</div>\n </div>\n \n <ng-template #financialYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">calendar_today</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentFinancialYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Academic Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"academicYearItems\" [config]=\"academicYearConfig\"\n [triggerTemplate]=\"academicYearTriggerTemplate\"\n (itemClick)=\"onAcademicYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Academic Year</div>\n </div>\n \n <ng-template #academicYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">school</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentAcademicYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Notifications Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown \n [items]=\"notificationItems\" \n [config]=\"notificationConfig\"\n [triggerTemplate]=\"notificationTriggerTemplate\"\n (itemClick)=\"onNotificationClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Notifications</div>\n </div>\n \n <ng-template #notificationTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-icon notification-icon\" [class.active]=\"isOpen\">\n <cide-ele-icon>notifications</cide-ele-icon>\n @if (unreadCount() > 0) {\n <div class=\"header-badge\">{{ unreadCount() > 99 ? '99+' : unreadCount() }}</div>\n }\n </div>\n </ng-template>\n\n <div class=\"header-divider\"></div>\n\n <!-- Profile with Dropdown -->\n <div class=\"header-icon user-profile\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"profileItems\" [config]=\"profileConfig\"\n [triggerTemplate]=\"triggerTemplate\"\n (itemClick)=\"onProfileClick($event)\">\n <ng-template #triggerTemplate>\n @if (appStateService.currentUser()?.user_photo_id_cyfm) {\n <div class=\"profile-avatar\">\n <img cideEleFileImage [fileId]=\"(appStateService.currentUser()?.user_photo_id_cyfm || '')\"\n [altText]=\"'User Profile Photo'\" class=\"tw-w-full tw-h-full tw-object-cover tw-rounded-full\">\n </div>\n } @else {\n <div class=\"profile-avatar\">\n <cide-ele-icon name=\"person\" class=\"tw-w-6 tw-h-6 tw-text-white\"></cide-ele-icon>\n </div>\n }\n </ng-template>\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">My Account</div>\n </div>\n </div>\n</header>", styles: [".cide-lyt-header{display:flex;align-items:center;justify-content:space-between;background:linear-gradient(to right,#fffffff2,#f9fafbf2);box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:20;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgba(229,231,235,.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-logo-container{height:100%;display:flex;align-items:center;padding:.5rem 0;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);border-radius:8px;outline:none}.header-logo-container img{height:30px;max-height:100%;transition:all .3s ease;border-radius:5px;overflow:hidden;box-shadow:0 1px 4px #0000000d}.header-logo-container:hover img{transform:scale(1.03);filter:brightness(1.05);box-shadow:0 2px 6px #00000014}.header-logo-container:after{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:linear-gradient(to bottom right,#fff0,#ffffff4d,#fff0);transform:rotate(30deg);opacity:0;transition:transform .6s ease,opacity .6s ease;pointer-events:none}.header-logo-container:hover:after,.header-logo-container:focus:after{opacity:1;transform:rotate(30deg) translate(50%,50%)}.header-search-container{flex-grow:1;max-width:600px;margin:0 2rem;position:relative;transition:all .3s ease}::ng-deep .header-search-container #cide_lyt_header_search{width:100%;background-color:#f9fafbcc;border-radius:20px!important;transition:all .3s ease;overflow:visible;transform:translateZ(0)}::ng-deep .header-search-container #cide_lyt_header_search:hover{box-shadow:0 3px 12px #00000014;background-color:#fff;transform:translateY(-1px)}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-input{background-color:transparent;font-size:.85rem!important;letter-spacing:.01em}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:#6b7280b3!important;font-size:1.1rem!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within{transform:translateY(-1px) scale(1.01)}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-input{border-color:#3b82f6!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-leading-icon{color:#3b82f6!important}.header-icons-container{display:flex;align-items:center;gap:1rem}.header-icon{position:relative;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-dropdown-container{position:relative;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-icon:before{content:\"\";position:absolute;inset:0;background-color:#3b82f61a;border-radius:.5rem;opacity:0;transform:scale(.8);transition:all .2s cubic-bezier(.4,0,.2,1)}.header-icon:hover:before{opacity:1;transform:scale(1)}.header-icon:hover{color:#3b82f6}.header-icon:active{transform:scale(.95)}.header-tooltip{position:absolute;bottom:-26px;left:50%;transform:translate(-50%);background-color:#374151e6;color:#fff;padding:.25rem .6rem;border-radius:.25rem;font-size:.7rem;white-space:nowrap;opacity:0;pointer-events:none;transition:all .2s cubic-bezier(.4,0,.2,1);z-index:1000;box-shadow:0 2px 5px #0003;letter-spacing:.01em;will-change:transform,opacity}.header-tooltip:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:5px;border-style:solid;border-color:transparent transparent rgba(55,65,81,.9) transparent}.header-icon:hover .header-tooltip{opacity:1;transform:translate(-50%) translateY(0)}.header-badge{position:absolute;top:0;right:0;min-width:16px;height:16px;border-radius:8px;background-color:#ef4444;color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 1px 3px #ef44444d;font-weight:600;z-index:2;transition:all .2s ease}.header-icon:hover .header-badge{transform:scale(1.1)}.header-divider{height:20px;width:1px;background-color:#e5e7ebcc;margin:0 6px}.header-year-dropdown-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.header-year-pill{position:relative;display:flex;align-items:center;padding:.25rem .625rem;background:linear-gradient(135deg,#3b82f61a,#2563eb26);border:1px solid rgba(59,130,246,.3);border-radius:9999px;color:#2563eb;font-size:.6875rem;font-weight:600;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;white-space:nowrap;box-shadow:0 1px 2px #3b82f61a;min-height:22px;height:22px;line-height:1}.header-year-pill:hover{background:linear-gradient(135deg,#3b82f626,#2563eb33);border-color:#3b82f666;transform:translateY(-1px);box-shadow:0 2px 6px #3b82f626}.header-year-pill-text{max-width:180px;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em;line-height:1;display:inline-block}::ng-deep .header-dropdown-container .dropdown-trigger{background:transparent!important;border:none!important;border-radius:0!important;padding:0!important;width:100%!important;height:100%!important;min-width:auto!important;box-shadow:none!important;display:flex!important;align-items:center!important;justify-content:center!important;transition:none!important;cursor:pointer!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover{background:transparent!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover .header-year-pill{background:linear-gradient(135deg,#3b82f626,#2563eb33)!important;border-color:#3b82f666!important;transform:translateY(-1px)!important;box-shadow:0 2px 6px #3b82f626!important}::ng-deep .header-dropdown-container .dropdown-trigger:focus,::ng-deep .header-dropdown-container .dropdown-trigger:focus-visible,::ng-deep .header-dropdown-container .dropdown-trigger:active{outline:none!important;box-shadow:0 2px 6px #3b82f626!important}.profile-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;font-size:.75rem;font-weight:600;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #2563eb33;transition:all .2s cubic-bezier(.4,0,.2,1);letter-spacing:-.5px;cursor:pointer;border:2px solid transparent}.profile-avatar:hover,.header-icon:hover .profile-avatar{transform:scale(1.08);box-shadow:0 3px 8px #2563eb4d;border-color:#3b82f64d}::ng-deep .user-profile .dropdown-trigger{background:transparent!important;border:none!important;padding:0!important;width:auto!important;height:auto!important;border-radius:0!important}::ng-deep .user-profile .dropdown-trigger:hover{background:transparent!important}::ng-deep .user-profile .dropdown-trigger:focus,::ng-deep .user-profile .dropdown-trigger:focus-visible,::ng-deep .user-profile .dropdown-trigger:active{outline:none!important;box-shadow:none!important}.header-avatar{width:36px;height:36px;border-radius:50%;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);border:2px solid transparent;box-shadow:0 2px 4px #0000001a}.header-avatar:hover{border-color:#3b82f6;transform:scale(1.05);box-shadow:0 3px 6px #3b82f64d}@media (max-width: 768px){.header-search-container{margin:0 1rem}.header-icons-container{gap:.5rem}}@media (max-width: 640px){.header-search-container{max-width:200px;margin:0 .5rem}}\n"] }]
2353
+ CideEleDropdownComponent, CideEleFileImageDirective], template: "<header id=\"cide-lyt-header-wrapper\" class=\"cide-lyt-header tw-w-full tw-select-none cide-lyt-header-wrapper-hide\">\n <!-- Logo Section -->\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <div class=\"header-logo-container tw-flex tw-items-center tw-gap-3 tw-cursor-pointer\" (click)=\"onLogoClick()\"\n (keydown.enter)=\"onLogoClick()\" (keydown.space)=\"onLogoClick()\" tabindex=\"0\" role=\"button\"\n aria-label=\"Navigate to home\" title=\"Click to go to control panel home\">\n @if (appStateService.activeEntity()?.syen_photo_id_cyfm) {\n <img cideEleFileImage [fileId]=\"(appStateService.activeEntity()?.syen_photo_id_cyfm || '')\"\n [altText]=\"'Entity Logo'\" class=\"tw-w-8 tw-h-8 tw-object-contain\">\n } @else {\n <cide-ele-icon name=\"business\" class=\"tw-w-8 tw-h-8 tw-text-blue-600\"></cide-ele-icon>\n }\n\n </div>\n @if (appStateService.activeEntity()?.syen_name) {\n <span\n class=\"tw-text-md tw-font-semibold tw-text-blue-600 hover:tw-text-blue-800 tw-cursor-pointer sm:block tw-transition-colors tw-duration-200 hover:tw-underline\"\n (click)=\"onEntityNameClick()\" title=\"Click to switch entity\">\n {{ appStateService.activeEntity()?.syen_name }}\n </span>\n }\n </div>\n <!-- Search Section -->\n <div class=\"header-search-container\">\n <cide-ele-input id=\"cide_lyt_header_search\" placeholder=\"Search...\" leadingIcon=\"search\"\n size=\"md\"></cide-ele-input>\n </div>\n\n <!-- Icons Section -->\n <div class=\"header-icons-container\">\n <!-- Financial Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"financialYearItems\" [config]=\"financialYearConfig\"\n [triggerTemplate]=\"financialYearTriggerTemplate\"\n (itemClick)=\"onFinancialYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Financial Year</div>\n </div>\n \n <ng-template #financialYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">calendar_today</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentFinancialYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Academic Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"academicYearItems\" [config]=\"academicYearConfig\"\n [triggerTemplate]=\"academicYearTriggerTemplate\"\n (itemClick)=\"onAcademicYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Academic Year</div>\n </div>\n \n <ng-template #academicYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">school</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentAcademicYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Notifications Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown \n [items]=\"notificationItems\" \n [config]=\"notificationConfig\"\n [triggerTemplate]=\"notificationTriggerTemplate\"\n [menuTemplate]=\"notificationMenuTemplate\"\n (itemClick)=\"onNotificationClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Notifications</div>\n </div>\n \n <ng-template #notificationTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-icon notification-icon\" [class.active]=\"isOpen\">\n <cide-ele-icon>notifications</cide-ele-icon>\n @if (unreadCount() > 0) {\n <div class=\"header-badge\">{{ unreadCount() > 99 ? '99+' : unreadCount() }}</div>\n }\n </div>\n </ng-template>\n\n <!-- Custom Notification Menu Template -->\n <ng-template #notificationMenuTemplate let-items=\"items\">\n <div class=\"notification-dropdown-menu\">\n <!-- Header -->\n <div class=\"notification-dropdown-header\">\n <h3 class=\"notification-dropdown-title\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"notification-unread-badge\">{{ unreadCount() }} unread</span>\n }\n </div>\n\n <!-- Notifications List -->\n <div class=\"notification-dropdown-body\">\n @if (notifications().length === 0) {\n <div class=\"notification-empty-state\">\n <cide-ele-icon class=\"notification-empty-icon\">notifications_off</cide-ele-icon>\n <p class=\"notification-empty-text\">No notifications</p>\n </div>\n } @else {\n @for (notif of notifications().slice(0, 10); track notif.id) {\n <div \n class=\"notification-item\" \n [class.unread]=\"!isNotificationRead(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <div class=\"notification-item-icon\">\n <cide-ele-icon [class]=\"getNotificationIconColorClass(notif.type)\">\n {{ getNotificationIcon(notif.type) }}\n </cide-ele-icon>\n </div>\n <div class=\"notification-item-content\">\n <div class=\"notification-item-header\">\n <h4 class=\"notification-item-title\">{{ notif.title }}</h4>\n <span class=\"notification-item-time\">{{ getTimeAgo(notif.timestamp) }}</span>\n </div>\n <p class=\"notification-item-message\">{{ notif.message }}</p>\n @if (notif.priority === 'urgent') {\n <span class=\"notification-priority-badge urgent\">Urgent</span>\n }\n </div>\n @if (!isNotificationRead(notif)) {\n <div class=\"notification-unread-indicator\"></div>\n }\n </div>\n }\n }\n </div>\n\n <!-- Footer Actions -->\n @if (notifications().length > 0) {\n <div class=\"notification-dropdown-footer\">\n <div class=\"notification-actions\">\n @if (unreadCount() > 0) {\n <button \n type=\"button\" \n class=\"notification-action-btn\"\n (click)=\"markAllAsRead()\">\n <cide-ele-icon>done_all</cide-ele-icon>\n <span>Mark all read</span>\n </button>\n }\n <button \n type=\"button\" \n class=\"notification-action-btn\"\n (click)=\"clearAllNotifications()\">\n <cide-ele-icon>clear_all</cide-ele-icon>\n <span>Clear all</span>\n </button>\n <button \n type=\"button\" \n class=\"notification-action-btn primary\"\n (click)=\"loadAllNotifications()\">\n <cide-ele-icon>list</cide-ele-icon>\n <span>View all</span>\n </button>\n </div>\n </div>\n }\n </div>\n </ng-template>\n\n <div class=\"header-divider\"></div>\n\n <!-- Profile with Dropdown -->\n <div class=\"header-icon user-profile\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"profileItems\" [config]=\"profileConfig\"\n [triggerTemplate]=\"triggerTemplate\"\n (itemClick)=\"onProfileClick($event)\">\n <ng-template #triggerTemplate>\n @if (appStateService.currentUser()?.user_photo_id_cyfm) {\n <div class=\"profile-avatar\">\n <img cideEleFileImage [fileId]=\"(appStateService.currentUser()?.user_photo_id_cyfm || '')\"\n [altText]=\"'User Profile Photo'\" class=\"tw-w-full tw-h-full tw-object-cover tw-rounded-full\">\n </div>\n } @else {\n <div class=\"profile-avatar\">\n <cide-ele-icon name=\"person\" class=\"tw-w-6 tw-h-6 tw-text-white\"></cide-ele-icon>\n </div>\n }\n </ng-template>\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">My Account</div>\n </div>\n </div>\n</header>", styles: [".cide-lyt-header{display:flex;align-items:center;justify-content:space-between;background:linear-gradient(to right,#fffffff2,#f9fafbf2);box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:20;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgba(229,231,235,.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-logo-container{height:100%;display:flex;align-items:center;padding:.5rem 0;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);border-radius:8px;outline:none}.header-logo-container img{height:30px;max-height:100%;transition:all .3s ease;border-radius:5px;overflow:hidden;box-shadow:0 1px 4px #0000000d}.header-logo-container:hover img{transform:scale(1.03);filter:brightness(1.05);box-shadow:0 2px 6px #00000014}.header-logo-container:after{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:linear-gradient(to bottom right,#fff0,#ffffff4d,#fff0);transform:rotate(30deg);opacity:0;transition:transform .6s ease,opacity .6s ease;pointer-events:none}.header-logo-container:hover:after,.header-logo-container:focus:after{opacity:1;transform:rotate(30deg) translate(50%,50%)}.header-search-container{flex-grow:1;max-width:600px;margin:0 2rem;position:relative;transition:all .3s ease}::ng-deep .header-search-container #cide_lyt_header_search{width:100%;background-color:#f9fafbcc;border-radius:20px!important;transition:all .3s ease;overflow:visible;transform:translateZ(0)}::ng-deep .header-search-container #cide_lyt_header_search:hover{box-shadow:0 3px 12px #00000014;background-color:#fff;transform:translateY(-1px)}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-input{background-color:transparent;font-size:.85rem!important;letter-spacing:.01em}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:#6b7280b3!important;font-size:1.1rem!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within{transform:translateY(-1px) scale(1.01)}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-input{border-color:#3b82f6!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-leading-icon{color:#3b82f6!important}.header-icons-container{display:flex;align-items:center;gap:1rem}.header-icon{position:relative;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-dropdown-container{position:relative;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-icon:before{content:\"\";position:absolute;inset:0;background-color:#3b82f61a;border-radius:.5rem;opacity:0;transform:scale(.8);transition:all .2s cubic-bezier(.4,0,.2,1)}.header-icon:hover:before{opacity:1;transform:scale(1)}.header-icon:hover{color:#3b82f6}.header-icon:active{transform:scale(.95)}.header-tooltip{position:absolute;bottom:-26px;left:50%;transform:translate(-50%);background-color:#374151e6;color:#fff;padding:.25rem .6rem;border-radius:.25rem;font-size:.7rem;white-space:nowrap;opacity:0;pointer-events:none;transition:all .2s cubic-bezier(.4,0,.2,1);z-index:1000;box-shadow:0 2px 5px #0003;letter-spacing:.01em;will-change:transform,opacity}.header-tooltip:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:5px;border-style:solid;border-color:transparent transparent rgba(55,65,81,.9) transparent}.header-icon:hover .header-tooltip{opacity:1;transform:translate(-50%) translateY(0)}.header-badge{position:absolute;top:0;right:0;min-width:16px;height:16px;border-radius:8px;background-color:#ef4444;color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 1px 3px #ef44444d;font-weight:600;z-index:2;transition:all .2s ease}.header-icon:hover .header-badge{transform:scale(1.1)}.header-divider{height:20px;width:1px;background-color:#e5e7ebcc;margin:0 6px}.header-year-dropdown-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.header-year-pill{position:relative;display:flex;align-items:center;padding:.25rem .625rem;background:linear-gradient(135deg,#3b82f61a,#2563eb26);border:1px solid rgba(59,130,246,.3);border-radius:9999px;color:#2563eb;font-size:.6875rem;font-weight:600;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;white-space:nowrap;box-shadow:0 1px 2px #3b82f61a;min-height:22px;height:22px;line-height:1}.header-year-pill:hover{background:linear-gradient(135deg,#3b82f626,#2563eb33);border-color:#3b82f666;transform:translateY(-1px);box-shadow:0 2px 6px #3b82f626}.header-year-pill-text{max-width:180px;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em;line-height:1;display:inline-block}::ng-deep .header-dropdown-container .dropdown-trigger{background:transparent!important;border:none!important;border-radius:0!important;padding:0!important;width:100%!important;height:100%!important;min-width:auto!important;box-shadow:none!important;display:flex!important;align-items:center!important;justify-content:center!important;transition:none!important;cursor:pointer!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover{background:transparent!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover .header-year-pill{background:linear-gradient(135deg,#3b82f626,#2563eb33)!important;border-color:#3b82f666!important;transform:translateY(-1px)!important;box-shadow:0 2px 6px #3b82f626!important}::ng-deep .header-dropdown-container .dropdown-trigger:focus,::ng-deep .header-dropdown-container .dropdown-trigger:focus-visible,::ng-deep .header-dropdown-container .dropdown-trigger:active{outline:none!important;box-shadow:0 2px 6px #3b82f626!important}.profile-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;font-size:.75rem;font-weight:600;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #2563eb33;transition:all .2s cubic-bezier(.4,0,.2,1);letter-spacing:-.5px;cursor:pointer;border:2px solid transparent}.profile-avatar:hover,.header-icon:hover .profile-avatar{transform:scale(1.08);box-shadow:0 3px 8px #2563eb4d;border-color:#3b82f64d}::ng-deep .user-profile .dropdown-trigger{background:transparent!important;border:none!important;padding:0!important;width:auto!important;height:auto!important;border-radius:0!important}::ng-deep .user-profile .dropdown-trigger:hover{background:transparent!important}::ng-deep .user-profile .dropdown-trigger:focus,::ng-deep .user-profile .dropdown-trigger:focus-visible,::ng-deep .user-profile .dropdown-trigger:active{outline:none!important;box-shadow:none!important}.header-avatar{width:36px;height:36px;border-radius:50%;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);border:2px solid transparent;box-shadow:0 2px 4px #0000001a}.header-avatar:hover{border-color:#3b82f6;transform:scale(1.05);box-shadow:0 3px 6px #3b82f64d}@media (max-width: 768px){.header-search-container{margin:0 1rem}.header-icons-container{gap:.5rem}}@media (max-width: 640px){.header-search-container{max-width:200px;margin:0 .5rem}}.notification-dropdown-menu{width:100%;max-width:400px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;overflow:hidden;display:flex;flex-direction:column;max-height:600px}.notification-dropdown-header{padding:16px 20px;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid rgba(255,255,255,.1)}.notification-dropdown-title{margin:0;font-size:1.1rem;font-weight:600;letter-spacing:-.01em}.notification-unread-badge{background:#ffffff40;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);padding:4px 12px;border-radius:12px;font-size:.75rem;font-weight:600;border:1px solid rgba(255,255,255,.3)}.notification-dropdown-body{flex:1;overflow-y:auto;max-height:450px;padding:8px 0}.notification-dropdown-body::-webkit-scrollbar{width:6px}.notification-dropdown-body::-webkit-scrollbar-track{background:#f1f1f1}.notification-dropdown-body::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.notification-dropdown-body::-webkit-scrollbar-thumb:hover{background:#a8a8a8}.notification-empty-state{padding:40px 20px;text-align:center;color:#9ca3af}.notification-empty-icon{font-size:3rem!important;color:#d1d5db!important;margin-bottom:12px}.notification-empty-text{margin:0;font-size:.9rem;color:#6b7280}.notification-item{display:flex;align-items:flex-start;padding:12px 20px;cursor:pointer;transition:all .2s ease;border-left:3px solid transparent;position:relative;gap:12px}.notification-item:hover{background:#f9fafb;border-left-color:#3b82f6}.notification-item.unread{background:#eff6ff;border-left-color:#3b82f6}.notification-item.unread:hover{background:#dbeafe}.notification-item-icon{flex-shrink:0;width:40px;height:40px;border-radius:10px;background:#f3f4f6;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.notification-item.unread .notification-item-icon{background:#dbeafe}.notification-item-icon cide-ele-icon{font-size:1.25rem!important}.notification-item-content{flex:1;min-width:0}.notification-item-header{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:4px}.notification-item-title{margin:0;font-size:.9rem;font-weight:600;color:#111827;line-height:1.4;flex:1}.notification-item-time{font-size:.75rem;color:#6b7280;white-space:nowrap;flex-shrink:0}.notification-item-message{margin:0;font-size:.85rem;color:#4b5563;line-height:1.5;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.notification-priority-badge{display:inline-block;margin-top:6px;padding:2px 8px;border-radius:4px;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.notification-priority-badge.urgent{background:#fee2e2;color:#dc2626}.notification-unread-indicator{position:absolute;top:16px;right:16px;width:8px;height:8px;border-radius:50%;background:#3b82f6;box-shadow:0 0 0 2px #fff}.notification-dropdown-footer{padding:12px 20px;background:#f9fafb;border-top:1px solid #e5e7eb}.notification-actions{display:flex;gap:8px;justify-content:flex-end}.notification-action-btn{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #e5e7eb;background:#fff;border-radius:6px;font-size:.8rem;color:#4b5563;cursor:pointer;transition:all .2s ease;font-weight:500}.notification-action-btn:hover{background:#f3f4f6;border-color:#d1d5db;color:#111827}.notification-action-btn.primary{background:#3b82f6;color:#fff;border-color:#3b82f6}.notification-action-btn.primary:hover{background:#2563eb;border-color:#2563eb}.notification-action-btn cide-ele-icon{font-size:1rem!important}\n"] }]
2195
2354
  }], ctorParameters: () => [], propDecorators: { triggerTemplate: [{
2196
2355
  type: ViewChild,
2197
2356
  args: ['triggerTemplate']
@@ -3406,8 +3565,8 @@ class CideLytSidedrawerWrapperComponent {
3406
3565
  }
3407
3566
  ngOnInit() {
3408
3567
  // Initialize the component map (You'd likely populate this from a config or service)
3409
- this.componentMap['drowar_notes'] = () => import('./cloud-ide-layout-sidedrawer-notes.component-sYWI-yH9.mjs').then(m => m.CideLytSidedrawerNotesComponent);
3410
- this.componentMap['drawer_theme'] = () => import('./cloud-ide-layout-drawer-theme.component-DMn2Cznf.mjs').then(m => m.CideLytDrawerThemeComponent);
3568
+ this.componentMap['drowar_notes'] = () => import('./cloud-ide-layout-sidedrawer-notes.component-Br9LCZ7q.mjs').then(m => m.CideLytSidedrawerNotesComponent);
3569
+ this.componentMap['drawer_theme'] = () => import('./cloud-ide-layout-drawer-theme.component-j59G67L1.mjs').then(m => m.CideLytDrawerThemeComponent);
3411
3570
  }
3412
3571
  async loadComponent(configFor) {
3413
3572
  console.log('🔍 SIDEDRAWER - Loading component:', configFor, 'Current tab:', this.currentTabId);
@@ -3930,7 +4089,7 @@ const layoutControlPannelChildRoutes = [{
3930
4089
  },
3931
4090
  {
3932
4091
  path: "home",
3933
- loadComponent: () => import('./cloud-ide-layout-home-wrapper.component-ZWphfyNz.mjs').then(c => c.CideLytHomeWrapperComponent),
4092
+ loadComponent: () => import('./cloud-ide-layout-home-wrapper.component-CI7dPMxZ.mjs').then(c => c.CideLytHomeWrapperComponent),
3934
4093
  canActivate: [authGuard],
3935
4094
  data: {
3936
4095
  reuseTab: true, // For CustomRouteReuseStrategy
@@ -5498,4 +5657,4 @@ var floatingEntityRightsSharing_component = /*#__PURE__*/Object.freeze({
5498
5657
  */
5499
5658
 
5500
5659
  export { AppStateHelperService as A, CideLytSharedWrapperComponent as C, ENVIRONMENT_CONFIG as E, CideLytSidebarService as a, CideLytRequestService as b, CideLytSidedrawerService as c, CideLytThemeService as d, AppStateService as e, CloudIdeLayoutService as f, CloudIdeLayoutComponent as g, CideLytSharedService as h, layoutControlPannelChildRoutes as i, CustomRouteReuseStrategy as j, CideLytUserStatusService as k, layoutRoutes as l, CacheManagerService as m, CideLytFileManagerService as n, CideLytFloatingEntityRightsSharingComponent as o, processThemeVariable as p, CideLytFloatingEntityRightsSharingService as q, setCSSVariable as s, themeFactory as t };
5501
- //# sourceMappingURL=cloud-ide-layout-cloud-ide-layout-CKLj-6xH.mjs.map
5660
+ //# sourceMappingURL=cloud-ide-layout-cloud-ide-layout-8S-2Ir2T.mjs.map