cloud-ide-layout 1.0.61 → 1.0.63

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-grBP43Ly.mjs → cloud-ide-layout-cloud-ide-layout-D1c2ObrF.mjs} +240 -33
  2. package/fesm2022/cloud-ide-layout-cloud-ide-layout-D1c2ObrF.mjs.map +1 -0
  3. package/fesm2022/{cloud-ide-layout-drawer-theme.component-BJ6T7meW.mjs → cloud-ide-layout-drawer-theme.component-t7-o6zko.mjs} +2 -2
  4. package/fesm2022/{cloud-ide-layout-drawer-theme.component-BJ6T7meW.mjs.map → cloud-ide-layout-drawer-theme.component-t7-o6zko.mjs.map} +1 -1
  5. package/fesm2022/{cloud-ide-layout-floating-entity-selection.component-BdzYa5wO.mjs → cloud-ide-layout-floating-entity-selection.component-mK3rgtPi.mjs} +2 -2
  6. package/fesm2022/{cloud-ide-layout-floating-entity-selection.component-BdzYa5wO.mjs.map → cloud-ide-layout-floating-entity-selection.component-mK3rgtPi.mjs.map} +1 -1
  7. package/fesm2022/{cloud-ide-layout-home-wrapper.component-CdzzQ1bR.mjs → cloud-ide-layout-home-wrapper.component-PzCCRZ1z.mjs} +2 -2
  8. package/fesm2022/{cloud-ide-layout-home-wrapper.component-CdzzQ1bR.mjs.map → cloud-ide-layout-home-wrapper.component-PzCCRZ1z.mjs.map} +1 -1
  9. package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-buxglvep.mjs → cloud-ide-layout-sidedrawer-notes.component-B9CanGJ0.mjs} +2 -2
  10. package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-buxglvep.mjs.map → cloud-ide-layout-sidedrawer-notes.component-B9CanGJ0.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-grBP43Ly.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-BdzYa5wO.mjs');
1269
+ const module = await import('./cloud-ide-layout-floating-entity-selection.component-mK3rgtPi.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
- // Load from API to get all notifications
1562
- this.notificationApiService.getNotifications({
1562
+ // Load from API to get all notifications (including read status)
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) {
@@ -1577,19 +1582,32 @@ class CideLytHeaderWrapperComponent {
1577
1582
  action_label: notif.not_action_label,
1578
1583
  priority: notif.not_priority || 'normal',
1579
1584
  created_at: new Date(notif.not_created_at),
1580
- timestamp: new Date(notif.not_created_at)
1585
+ timestamp: new Date(notif.not_created_at),
1586
+ // Store read status for filtering
1587
+ isRead: notif.not_status === 'read' || notif.not_read_at !== undefined
1581
1588
  }));
1582
1589
  console.log('[Notifications] Converted API payloads:', apiPayloads.length);
1583
- // Merge WebSocket and API notifications (WebSocket takes priority for duplicates)
1584
- const mergedNotifications = [...wsNotifications];
1590
+ // Merge WebSocket and API notifications (API takes priority for read status)
1591
+ const mergedNotifications = [];
1592
+ // Add API notifications first (they have read status)
1585
1593
  apiPayloads.forEach(apiNotif => {
1586
- if (!mergedNotifications.find(n => n.id === apiNotif.id)) {
1587
- mergedNotifications.push(apiNotif);
1594
+ mergedNotifications.push(apiNotif);
1595
+ });
1596
+ // Add WebSocket notifications that aren't in API (new real-time notifications)
1597
+ wsNotifications.forEach(wsNotif => {
1598
+ if (!mergedNotifications.find(n => n.id === wsNotif.id)) {
1599
+ mergedNotifications.push({ ...wsNotif, isRead: false });
1588
1600
  }
1589
1601
  });
1590
1602
  // Sort by timestamp (newest first)
1591
1603
  mergedNotifications.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
1592
1604
  console.log('[Notifications] Total merged notifications:', mergedNotifications.length);
1605
+ // Update WebSocket service with read status
1606
+ if (this.wsNotificationService) {
1607
+ // Update unread count based on read status
1608
+ const unread = mergedNotifications.filter(n => !n.isRead);
1609
+ // Note: WebSocket service manages its own unread count, but we sync here
1610
+ }
1593
1611
  this.notifications.set(mergedNotifications);
1594
1612
  this.updateNotificationDropdown();
1595
1613
  }
@@ -1617,25 +1635,58 @@ class CideLytHeaderWrapperComponent {
1617
1635
  */
1618
1636
  updateNotificationDropdown() {
1619
1637
  const notifs = this.notifications();
1620
- this.notificationItems = notifs.slice(0, 10).map(notif => ({
1638
+ const unreadCount = this.unreadCount();
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 => ({
1621
1644
  id: notif.id,
1622
1645
  label: notif.title,
1623
- description: notif.message,
1624
1646
  icon: this.getNotificationIcon(notif.type),
1625
1647
  iconColor: this.getNotificationIconColor(notif.type),
1626
- badge: notif.priority === 'urgent' ? 'Urgent' : undefined,
1627
- badgeColor: notif.priority === 'urgent' ? 'tw-bg-red-500' : undefined
1648
+ // Note: description is not supported by DropdownItem interface, but keeping for future use
1649
+ // description: notif.message,
1628
1650
  }));
1629
- // Add "View All" option if there are notifications
1651
+ // Add action buttons if there are notifications
1630
1652
  if (notifs.length > 0) {
1653
+ // Add divider before actions
1654
+ this.notificationItems.push({
1655
+ id: 'divider-1',
1656
+ label: '',
1657
+ divider: true
1658
+ });
1659
+ // Add "Mark All as Read" if there are unread notifications
1660
+ if (unreadCount > 0) {
1661
+ this.notificationItems.push({
1662
+ id: 'mark-all-read',
1663
+ label: 'Mark All as Read',
1664
+ icon: 'done_all',
1665
+ iconColor: 'tw-text-blue-500'
1666
+ });
1667
+ }
1668
+ // Add "Clear All" option (only if there are notifications)
1669
+ this.notificationItems.push({
1670
+ id: 'clear-all',
1671
+ label: 'Clear All',
1672
+ icon: 'clear_all',
1673
+ iconColor: 'tw-text-red-500',
1674
+ textColor: 'tw-text-red-600',
1675
+ hoverBgColor: 'hover:tw-bg-red-50'
1676
+ });
1677
+ // Add divider before "View All"
1631
1678
  this.notificationItems.push({
1632
- id: 'divider',
1679
+ id: 'divider-2',
1633
1680
  label: '',
1634
1681
  divider: true
1635
1682
  });
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';
1636
1687
  this.notificationItems.push({
1637
1688
  id: 'view-all',
1638
- label: 'View All Notifications',
1689
+ label: viewAllLabel,
1639
1690
  icon: 'list',
1640
1691
  iconColor: 'tw-text-blue-500'
1641
1692
  });
@@ -1680,30 +1731,186 @@ class CideLytHeaderWrapperComponent {
1680
1731
  * Handle notification dropdown item click
1681
1732
  */
1682
1733
  onNotificationClick(item) {
1734
+ // Handle action buttons
1735
+ if (item.id === 'mark-all-read') {
1736
+ this.markAllAsRead();
1737
+ return;
1738
+ }
1739
+ if (item.id === 'clear-all') {
1740
+ this.clearAllNotifications();
1741
+ return;
1742
+ }
1683
1743
  if (item.id === 'view-all') {
1684
- // Navigate to notifications page or open full panel
1685
- console.log('View all notifications');
1744
+ // Show all notifications - for now, just reload with more items
1745
+ console.log('[Notifications] View all notifications');
1746
+ this.loadAllNotifications();
1686
1747
  return;
1687
1748
  }
1688
- if (item.id === 'no-notifications' || item.id === 'divider') {
1749
+ if (item.id === 'no-notifications' || item.id === 'divider' || item.id === 'divider-1' || item.id === 'divider-2') {
1689
1750
  return;
1690
1751
  }
1691
- // Mark notification as read
1752
+ // Mark notification as read when clicked
1753
+ this.markNotificationAsRead(String(item.id));
1754
+ // Navigate to action URL if available
1755
+ const notification = this.notifications().find(n => n.id === item.id);
1756
+ if (notification?.action_url) {
1757
+ this.router.navigate([notification.action_url]);
1758
+ }
1759
+ }
1760
+ /**
1761
+ * Mark a single notification as read
1762
+ */
1763
+ markNotificationAsRead(notificationId) {
1764
+ console.log('[Notifications] Marking as read:', notificationId);
1765
+ // Mark in WebSocket service
1692
1766
  if (this.wsNotificationService) {
1693
- this.wsNotificationService.markAsRead(String(item.id));
1767
+ this.wsNotificationService.markAsRead(notificationId);
1694
1768
  }
1695
- this.notificationApiService.markAsRead(String(item.id)).subscribe({
1696
- next: () => {
1769
+ // Mark in API
1770
+ this.notificationApiService.markAsRead(notificationId).subscribe({
1771
+ next: (response) => {
1772
+ console.log('[Notifications] Marked as read successfully:', response);
1773
+ // Reload notifications to update unread count
1697
1774
  this.loadNotifications();
1698
1775
  },
1699
1776
  error: (error) => {
1700
- console.error('Error marking notification as read:', error);
1777
+ console.error('[Notifications] Error marking notification as read:', error);
1778
+ console.error('[Notifications] Error details:', {
1779
+ status: error?.status,
1780
+ statusText: error?.statusText,
1781
+ message: error?.message,
1782
+ url: error?.url
1783
+ });
1784
+ // Still reload to get updated state
1785
+ this.loadNotifications();
1701
1786
  }
1702
1787
  });
1703
- // Navigate to action URL if available
1704
- const notification = this.notifications().find(n => n.id === item.id);
1705
- if (notification?.action_url) {
1706
- this.router.navigate([notification.action_url]);
1788
+ }
1789
+ /**
1790
+ * Mark all notifications as read
1791
+ */
1792
+ markAllAsRead() {
1793
+ console.log('[Notifications] Marking all as read');
1794
+ this.notificationApiService.markAllAsRead().subscribe({
1795
+ next: (response) => {
1796
+ console.log('[Notifications] All notifications marked as read successfully:', response);
1797
+ // Reload notifications to update unread count
1798
+ this.loadNotifications();
1799
+ },
1800
+ error: (error) => {
1801
+ console.error('[Notifications] Error marking all as read:', error);
1802
+ console.error('[Notifications] Error details:', {
1803
+ status: error?.status,
1804
+ statusText: error?.statusText,
1805
+ message: error?.message,
1806
+ url: error?.url
1807
+ });
1808
+ // Still reload to get updated state
1809
+ this.loadNotifications();
1810
+ }
1811
+ });
1812
+ }
1813
+ /**
1814
+ * Clear all notifications (mark all as read and remove from view)
1815
+ */
1816
+ clearAllNotifications() {
1817
+ if (confirm('Are you sure you want to clear all notifications? This will mark them all as read.')) {
1818
+ console.log('[Notifications] Clearing all notifications');
1819
+ // First mark all as read
1820
+ this.notificationApiService.markAllAsRead().subscribe({
1821
+ next: (response) => {
1822
+ console.log('[Notifications] All notifications marked as read:', response);
1823
+ // Filter current notifications to mark them as read locally
1824
+ const currentNotifs = this.notifications();
1825
+ const updatedNotifs = currentNotifs.map(notif => ({
1826
+ ...notif,
1827
+ isRead: true
1828
+ }));
1829
+ // Clear notifications from view (they're all read now)
1830
+ this.notifications.set([]);
1831
+ this.updateNotificationDropdown();
1832
+ // Reload after a short delay to get updated state from server
1833
+ // This will show empty or only new unread notifications
1834
+ setTimeout(() => {
1835
+ this.loadNotifications();
1836
+ }, 500);
1837
+ },
1838
+ error: (error) => {
1839
+ console.error('[Notifications] Error clearing all notifications:', error);
1840
+ console.error('[Notifications] Error details:', {
1841
+ status: error?.status,
1842
+ statusText: error?.statusText,
1843
+ message: error?.message,
1844
+ url: error?.url
1845
+ });
1846
+ // Still try to reload
1847
+ this.loadNotifications();
1848
+ }
1849
+ });
1850
+ }
1851
+ }
1852
+ /**
1853
+ * Load all notifications (for "View All" functionality)
1854
+ */
1855
+ loadAllNotifications() {
1856
+ try {
1857
+ const wsNotifications = this.wsNotificationService?.allNotifications() || [];
1858
+ console.log('[Notifications] Loading all notifications (View All)');
1859
+ // Load more notifications from API (increase pageSize)
1860
+ this.notificationApiService.getNotifications({
1861
+ pageSize: 100 // Load more for "View All"
1862
+ }).subscribe({
1863
+ next: (response) => {
1864
+ console.log('[Notifications] All notifications API response:', response);
1865
+ if (response && response.success && response.data) {
1866
+ // Convert server notifications to notification payloads
1867
+ const apiPayloads = response.data.map((notif) => ({
1868
+ id: String(notif._id),
1869
+ type: notif.not_type || 'info',
1870
+ category: notif.not_category,
1871
+ title: notif.not_title,
1872
+ message: notif.not_message,
1873
+ data: notif.not_data,
1874
+ action_url: notif.not_action_url,
1875
+ action_label: notif.not_action_label,
1876
+ priority: notif.not_priority || 'normal',
1877
+ created_at: new Date(notif.not_created_at),
1878
+ timestamp: new Date(notif.not_created_at),
1879
+ isRead: notif.not_status === 'read' || notif.not_read_at !== undefined
1880
+ }));
1881
+ // Merge WebSocket and API notifications
1882
+ const mergedNotifications = [];
1883
+ // Add API notifications first
1884
+ apiPayloads.forEach(apiNotif => {
1885
+ mergedNotifications.push(apiNotif);
1886
+ });
1887
+ // Add WebSocket notifications that aren't in API
1888
+ wsNotifications.forEach(wsNotif => {
1889
+ if (!mergedNotifications.find(n => n.id === wsNotif.id)) {
1890
+ mergedNotifications.push({ ...wsNotif, isRead: false });
1891
+ }
1892
+ });
1893
+ // Sort by timestamp (newest first)
1894
+ mergedNotifications.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
1895
+ console.log('[Notifications] Total notifications loaded:', mergedNotifications.length);
1896
+ this.notifications.set(mergedNotifications);
1897
+ this.updateNotificationDropdown();
1898
+ }
1899
+ else {
1900
+ console.warn('[Notifications] API response invalid');
1901
+ this.notifications.set(wsNotifications);
1902
+ this.updateNotificationDropdown();
1903
+ }
1904
+ },
1905
+ error: (error) => {
1906
+ console.error('[Notifications] Error loading all notifications:', error);
1907
+ this.notifications.set(wsNotifications);
1908
+ this.updateNotificationDropdown();
1909
+ }
1910
+ });
1911
+ }
1912
+ catch (error) {
1913
+ console.error('[Notifications] Error in loadAllNotifications:', error);
1707
1914
  }
1708
1915
  }
1709
1916
  ngAfterViewInit() {
@@ -3310,8 +3517,8 @@ class CideLytSidedrawerWrapperComponent {
3310
3517
  }
3311
3518
  ngOnInit() {
3312
3519
  // Initialize the component map (You'd likely populate this from a config or service)
3313
- this.componentMap['drowar_notes'] = () => import('./cloud-ide-layout-sidedrawer-notes.component-buxglvep.mjs').then(m => m.CideLytSidedrawerNotesComponent);
3314
- this.componentMap['drawer_theme'] = () => import('./cloud-ide-layout-drawer-theme.component-BJ6T7meW.mjs').then(m => m.CideLytDrawerThemeComponent);
3520
+ this.componentMap['drowar_notes'] = () => import('./cloud-ide-layout-sidedrawer-notes.component-B9CanGJ0.mjs').then(m => m.CideLytSidedrawerNotesComponent);
3521
+ this.componentMap['drawer_theme'] = () => import('./cloud-ide-layout-drawer-theme.component-t7-o6zko.mjs').then(m => m.CideLytDrawerThemeComponent);
3315
3522
  }
3316
3523
  async loadComponent(configFor) {
3317
3524
  console.log('🔍 SIDEDRAWER - Loading component:', configFor, 'Current tab:', this.currentTabId);
@@ -3834,7 +4041,7 @@ const layoutControlPannelChildRoutes = [{
3834
4041
  },
3835
4042
  {
3836
4043
  path: "home",
3837
- loadComponent: () => import('./cloud-ide-layout-home-wrapper.component-CdzzQ1bR.mjs').then(c => c.CideLytHomeWrapperComponent),
4044
+ loadComponent: () => import('./cloud-ide-layout-home-wrapper.component-PzCCRZ1z.mjs').then(c => c.CideLytHomeWrapperComponent),
3838
4045
  canActivate: [authGuard],
3839
4046
  data: {
3840
4047
  reuseTab: true, // For CustomRouteReuseStrategy
@@ -5402,4 +5609,4 @@ var floatingEntityRightsSharing_component = /*#__PURE__*/Object.freeze({
5402
5609
  */
5403
5610
 
5404
5611
  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 };
5405
- //# sourceMappingURL=cloud-ide-layout-cloud-ide-layout-grBP43Ly.mjs.map
5612
+ //# sourceMappingURL=cloud-ide-layout-cloud-ide-layout-D1c2ObrF.mjs.map