cloud-ide-layout 1.0.156 → 1.0.157
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/{cloud-ide-layout-cloud-ide-layout-C32z4h9X.mjs → cloud-ide-layout-cloud-ide-layout-B84fwD52.mjs} +44 -20
- package/fesm2022/cloud-ide-layout-cloud-ide-layout-B84fwD52.mjs.map +1 -0
- package/fesm2022/{cloud-ide-layout-dashboard-manager.component-BBgc6ErN.mjs → cloud-ide-layout-dashboard-manager.component-DStneI1a.mjs} +2 -2
- package/fesm2022/{cloud-ide-layout-dashboard-manager.component-BBgc6ErN.mjs.map → cloud-ide-layout-dashboard-manager.component-DStneI1a.mjs.map} +1 -1
- package/fesm2022/{cloud-ide-layout-drawer-theme.component-B7cUmWIU.mjs → cloud-ide-layout-drawer-theme.component-DoXf1jLH.mjs} +2 -2
- package/fesm2022/{cloud-ide-layout-drawer-theme.component-B7cUmWIU.mjs.map → cloud-ide-layout-drawer-theme.component-DoXf1jLH.mjs.map} +1 -1
- package/fesm2022/{cloud-ide-layout-floating-entity-selection.component-CHl6Wpcw.mjs → cloud-ide-layout-floating-entity-selection.component-DOshDEHh.mjs} +2 -2
- package/fesm2022/{cloud-ide-layout-floating-entity-selection.component-CHl6Wpcw.mjs.map → cloud-ide-layout-floating-entity-selection.component-DOshDEHh.mjs.map} +1 -1
- package/fesm2022/{cloud-ide-layout-home-wrapper.component-DxpQcOIo.mjs → cloud-ide-layout-home-wrapper.component-DjVrTMDM.mjs} +2 -2
- package/fesm2022/{cloud-ide-layout-home-wrapper.component-DxpQcOIo.mjs.map → cloud-ide-layout-home-wrapper.component-DjVrTMDM.mjs.map} +1 -1
- package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-Ban3rP_a.mjs → cloud-ide-layout-sidedrawer-notes.component-DOxcfBdm.mjs} +2 -2
- package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-Ban3rP_a.mjs.map → cloud-ide-layout-sidedrawer-notes.component-DOxcfBdm.mjs.map} +1 -1
- package/fesm2022/cloud-ide-layout.mjs +1 -1
- package/package.json +1 -1
- package/fesm2022/cloud-ide-layout-cloud-ide-layout-C32z4h9X.mjs.map +0 -1
|
@@ -55,8 +55,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
55
55
|
}], ctorParameters: () => [] });
|
|
56
56
|
|
|
57
57
|
class CideLytSidebarService {
|
|
58
|
-
sidebarMenueVisible = false;
|
|
59
58
|
http = inject(HttpClient);
|
|
59
|
+
// Track sidebar visibility state using signal
|
|
60
|
+
sidebarVisibleState = signal(false, ...(ngDevMode ? [{ debugName: "sidebarVisibleState" }] : []));
|
|
61
|
+
sidebarVisible = this.sidebarVisibleState.asReadonly();
|
|
60
62
|
// Track sidebar collapsed state
|
|
61
63
|
collapsedState = new BehaviorSubject(false);
|
|
62
64
|
collapsedState$ = this.collapsedState.asObservable();
|
|
@@ -84,16 +86,22 @@ class CideLytSidebarService {
|
|
|
84
86
|
}
|
|
85
87
|
// Hide Sidebar
|
|
86
88
|
hideSidebar() {
|
|
87
|
-
this.
|
|
89
|
+
this.sidebarVisibleState.set(false);
|
|
88
90
|
document.querySelector(`#cide-lyt-sidebar-page`)?.classList.add('cide-lyt-sidebar-page-hide');
|
|
89
91
|
document.querySelector(`body`)?.classList.remove('cide-lyt-sidebar-exist');
|
|
90
92
|
}
|
|
91
93
|
// Show Sidebar
|
|
92
94
|
showSidebar() {
|
|
93
|
-
this.
|
|
95
|
+
this.sidebarVisibleState.set(true);
|
|
94
96
|
document.querySelector(`#cide-lyt-sidebar-page`)?.classList.remove('cide-lyt-sidebar-page-hide');
|
|
95
97
|
document.querySelector(`body`)?.classList.add('cide-lyt-sidebar-exist');
|
|
96
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Get current sidebar visibility state (for backward compatibility)
|
|
101
|
+
*/
|
|
102
|
+
get sidebarMenueVisible() {
|
|
103
|
+
return this.sidebarVisibleState();
|
|
104
|
+
}
|
|
97
105
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideLytSidebarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
98
106
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideLytSidebarService, providedIn: 'root' });
|
|
99
107
|
}
|
|
@@ -1400,7 +1408,7 @@ class CideLytFloatingEntitySelectionService {
|
|
|
1400
1408
|
}
|
|
1401
1409
|
try {
|
|
1402
1410
|
// Use relative import to avoid circular dependency
|
|
1403
|
-
const module = await import('./cloud-ide-layout-floating-entity-selection.component-
|
|
1411
|
+
const module = await import('./cloud-ide-layout-floating-entity-selection.component-DOshDEHh.mjs');
|
|
1404
1412
|
if (module.CideLytFloatingEntitySelectionComponent) {
|
|
1405
1413
|
this.containerService.registerComponent('entity-selection-header', module.CideLytFloatingEntitySelectionComponent);
|
|
1406
1414
|
console.log('✅ Entity selection component registered successfully');
|
|
@@ -2379,6 +2387,8 @@ class CideLytHeaderWrapperComponent {
|
|
|
2379
2387
|
sidebarService = inject(CideLytSidebarService);
|
|
2380
2388
|
// Track sidebar collapsed state
|
|
2381
2389
|
isSidebarCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "isSidebarCollapsed" }] : []));
|
|
2390
|
+
// Track sidebar visibility state
|
|
2391
|
+
isSidebarVisible = signal(false, ...(ngDevMode ? [{ debugName: "isSidebarVisible" }] : []));
|
|
2382
2392
|
constructor() {
|
|
2383
2393
|
// Trigger page-data workflow for header (without rendering breadcrumb)
|
|
2384
2394
|
const entityId = this.appStateService.activeEntity()?._id || undefined;
|
|
@@ -2390,6 +2400,26 @@ class CideLytHeaderWrapperComponent {
|
|
|
2390
2400
|
next: () => { },
|
|
2391
2401
|
error: () => { }
|
|
2392
2402
|
});
|
|
2403
|
+
// Track sidebar visibility changes using effect
|
|
2404
|
+
effect(() => {
|
|
2405
|
+
const isVisible = this.sidebarService.sidebarVisible();
|
|
2406
|
+
this.isSidebarVisible.set(isVisible);
|
|
2407
|
+
});
|
|
2408
|
+
// Check initial sidebar visibility from DOM (in case sidebar was shown/hidden before service initialization)
|
|
2409
|
+
if (typeof document !== 'undefined') {
|
|
2410
|
+
const sidebarPage = document.querySelector('#cide-lyt-sidebar-page');
|
|
2411
|
+
const hasHideClass = sidebarPage?.classList.contains('cide-lyt-sidebar-page-hide');
|
|
2412
|
+
const initialVisibility = !hasHideClass;
|
|
2413
|
+
if (initialVisibility !== this.sidebarService.sidebarVisible()) {
|
|
2414
|
+
// Sync service state with DOM state
|
|
2415
|
+
if (initialVisibility) {
|
|
2416
|
+
this.sidebarService.showSidebar();
|
|
2417
|
+
}
|
|
2418
|
+
else {
|
|
2419
|
+
this.sidebarService.hideSidebar();
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2393
2423
|
}
|
|
2394
2424
|
ngOnInit() {
|
|
2395
2425
|
// Initialize audio context early to avoid browser autoplay restrictions
|
|
@@ -2411,8 +2441,10 @@ class CideLytHeaderWrapperComponent {
|
|
|
2411
2441
|
.subscribe(isCollapsed => {
|
|
2412
2442
|
this.isSidebarCollapsed.set(isCollapsed);
|
|
2413
2443
|
});
|
|
2414
|
-
// Set initial sidebar state
|
|
2444
|
+
// Set initial sidebar collapsed state
|
|
2415
2445
|
this.isSidebarCollapsed.set(this.sidebarService.isCollapsed());
|
|
2446
|
+
// Set initial sidebar visibility state
|
|
2447
|
+
this.isSidebarVisible.set(this.sidebarService.sidebarVisible());
|
|
2416
2448
|
this.loadFinancialYears();
|
|
2417
2449
|
this.loadAcademicYears();
|
|
2418
2450
|
// Initialize notification dropdown with empty state
|
|
@@ -2424,14 +2456,6 @@ class CideLytHeaderWrapperComponent {
|
|
|
2424
2456
|
* Toggle sidebar collapsed state
|
|
2425
2457
|
*/
|
|
2426
2458
|
toggleSidebar() {
|
|
2427
|
-
// Add animation class to button for icon animation
|
|
2428
|
-
const button = document.querySelector('.header-sidebar-toggle');
|
|
2429
|
-
if (button) {
|
|
2430
|
-
button.classList.add('animating');
|
|
2431
|
-
setTimeout(() => {
|
|
2432
|
-
button.classList.remove('animating');
|
|
2433
|
-
}, 400); // Match animation duration
|
|
2434
|
-
}
|
|
2435
2459
|
this.sidebarService.toggleSidebar();
|
|
2436
2460
|
// Find and trigger the sidebar toggle button
|
|
2437
2461
|
const sidebarToggle = document.querySelector('.collapse-toggle');
|
|
@@ -3591,12 +3615,12 @@ class CideLytHeaderWrapperComponent {
|
|
|
3591
3615
|
this.floatingContainerService.bringToFront(containerId);
|
|
3592
3616
|
}
|
|
3593
3617
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideLytHeaderWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3594
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", 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 }, { propertyName: "notificationDropdown", first: true, predicate: ["notificationDropdown"], 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 <!-- Sidebar Toggle Button - Always visible -->\n <button \n class=\"header-sidebar-toggle tw-flex tw-items-center tw-justify-center tw-w-10 tw-h-10 tw-rounded-lg tw-text-gray-600 hover:tw-text-gray-900 hover:tw-bg-gray-100 tw-transition-all tw-duration-300 tw-cursor-pointer tw-mr-1\"\n (click)=\"toggleSidebar()\"\n (keydown.enter)=\"toggleSidebar()\"\n (keydown.space)=\"toggleSidebar()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"isSidebarCollapsed() ? 'Expand sidebar menu' : 'Collapse sidebar menu'\"\n [attr.title]=\"isSidebarCollapsed() ? 'Expand sidebar menu' : 'Collapse sidebar menu'\">\n <cide-ele-icon size=\"md\" type=\"none\">\n {{ isSidebarCollapsed() ? 'menu' : 'menu_open' }}\n </cide-ele-icon>\n </button>\n \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 #notificationDropdown\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=\"tw-min-w-[380px] tw-bg-white dark:tw-bg-gray-800 tw-rounded-xl tw-shadow-2xl tw-overflow-hidden tw-text-gray-900 dark:tw-text-gray-100\">\n <!-- Header - Fixed/Sticky -->\n <div class=\"tw-sticky tw-top-0 tw-z-10 tw-px-2.5 tw-py-1 tw-bg-white dark:tw-bg-gray-800 tw-flex tw-justify-between tw-items-center tw-border-b tw-border-gray-200 dark:tw-border-gray-700 tw-backdrop-blur-sm\">\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <div class=\"tw-w-5 tw-h-5 tw-bg-blue-500 tw-rounded tw-flex tw-items-center tw-justify-center tw-shadow-sm\">\n <cide-ele-icon class=\"!tw-text-[10px] !tw-text-white\">notifications</cide-ele-icon>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <h3 class=\"tw-m-0 tw-text-[10px] tw-font-bold tw-text-gray-900 dark:tw-text-gray-100 tw-leading-none\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"tw-bg-red-500 tw-text-white tw-px-1 tw-py-0 tw-rounded-full tw-text-[7px] tw-font-bold tw-leading-none tw-animate-pulse\">{{ unreadCount() }}</span>\n }\n </div>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-0.5\">\n <button \n type=\"button\"\n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-600 dark:tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-200 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-600 hover:tw-text-gray-900 dark:hover:tw-text-gray-200\"\n (click)=\"openNotificationSettings(); $event.stopPropagation()\"\n title=\"Notification Settings\">\n <cide-ele-icon class=\"!tw-text-xs\">settings</cide-ele-icon>\n </button>\n @if (unreadCount() > 0) {\n <button \n type=\"button\"\n class=\"tw-bg-blue-500 tw-text-white tw-px-1 tw-py-0.5 tw-rounded tw-text-[8px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-flex tw-items-center tw-gap-0.5 tw-shadow-sm hover:tw-bg-blue-600 hover:tw-scale-105\"\n (click)=\"markAllAsRead(); $event.stopPropagation()\"\n title=\"Mark all as read\">\n <cide-ele-icon class=\"!tw-text-[9px]\">done_all</cide-ele-icon>\n </button>\n }\n <button \n type=\"button\" \n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-600 dark:tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-200 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-600 hover:tw-text-gray-900 dark:hover:tw-text-gray-200 hover:tw-rotate-90\"\n (click)=\"closeNotificationDropdown($event)\"\n title=\"Close\">\n <cide-ele-icon class=\"!tw-text-xs\">close</cide-ele-icon>\n </button>\n </div>\n </div>\n\n <!-- Notifications List -->\n <div class=\"tw-overflow-x-hidden notification-scroll-container tw-bg-white dark:tw-bg-gray-800 tw-text-gray-900 dark:tw-text-gray-100\">\n @if (notifications().length === 0) {\n <div class=\"tw-py-16 tw-px-4 tw-text-center tw-bg-white dark:tw-bg-gray-800\">\n <cide-ele-icon class=\"!tw-text-6xl !tw-text-gray-300 dark:!tw-text-gray-600 tw-mb-3\">notifications_off</cide-ele-icon>\n <p class=\"tw-m-0 tw-text-sm tw-text-gray-600 dark:tw-text-gray-400 tw-font-medium\">No notifications yet</p>\n <p class=\"tw-m-0 tw-mt-1 tw-text-xs tw-text-gray-500 dark:tw-text-gray-500\">You're all caught up!</p>\n </div>\n } @else {\n @for (notif of notifications().slice(0, 15); track notif.id) {\n <div \n class=\"tw-flex tw-items-start tw-px-3 tw-py-2 tw-cursor-pointer tw-transition-all tw-duration-300 tw-relative tw-gap-2 tw-border-b tw-border-gray-200 dark:tw-border-gray-700 last:tw-border-b-0 hover:tw-bg-gray-50 dark:hover:tw-bg-gray-700 tw-transform tw-ease-in-out tw-bg-white dark:tw-bg-gray-800 tw-text-gray-900 dark:tw-text-gray-100\"\n [class.tw-border-l-2]=\"!isNotificationRead(notif)\"\n [class.tw-border-l-blue-500]=\"!isNotificationRead(notif)\"\n [class.dark:tw-border-l-blue-400]=\"!isNotificationRead(notif)\"\n [class.tw-bg-blue-50]=\"!isNotificationRead(notif)\"\n [class.dark:tw-bg-gray-700]=\"!isNotificationRead(notif)\"\n [class.-tw-translate-x-full]=\"isNotificationAnimating(notif)\"\n [class.tw-opacity-0]=\"isNotificationAnimating(notif)\"\n [class.tw-max-h-0]=\"isNotificationAnimating(notif)\"\n [class.tw-overflow-hidden]=\"isNotificationAnimating(notif)\"\n [class.tw-mb-0]=\"isNotificationAnimating(notif)\"\n [class.tw-p-0]=\"isNotificationAnimating(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <!-- Icon/Avatar -->\n <div class=\"tw-flex-shrink-0 tw-relative\">\n <div class=\"tw-w-9 tw-h-9 tw-rounded-full tw-overflow-hidden tw-bg-gradient-to-br tw-from-blue-500 tw-to-blue-600 tw-flex tw-items-center tw-justify-center tw-shadow-sm tw-ring-1 tw-ring-white\">\n @if (getNotificationAvatar(notif)) {\n <img \n cideEleFileImage \n [fileId]=\"getNotificationAvatar(notif) || ''\"\n [altText]=\"getNotificationName(notif)\"\n class=\"tw-w-full tw-h-full tw-object-cover\">\n } @else {\n <cide-ele-icon class=\"!tw-text-base !tw-text-white\">{{ getNotificationIcon(notif.type) }}</cide-ele-icon>\n }\n </div>\n <!-- Green online indicator -->\n <div class=\"tw-absolute tw-bottom-0 tw-right-0 tw-w-2 tw-h-2 tw-bg-green-500 tw-rounded-full tw-border tw-border-white\"></div>\n </div>\n\n <!-- Content -->\n <div class=\"tw-flex-1 tw-min-w-0\">\n <!-- Title and relative time -->\n <div class=\"tw-flex tw-items-start tw-justify-between tw-gap-1.5 tw-mb-0.5\">\n <div class=\"tw-flex-1 tw-min-w-0\">\n <h4 class=\"tw-m-0 tw-text-[11px] tw-font-bold tw-text-gray-900 dark:tw-text-gray-100 tw-leading-tight\">\n <span class=\"tw-text-blue-600 dark:tw-text-blue-400\">{{ getNotificationName(notif) }}</span><span class=\"tw-font-normal tw-text-gray-800 dark:tw-text-gray-300\"> {{ getNotificationAction(notif) }}</span>\n </h4>\n <p class=\"tw-m-0 tw-text-[9px] tw-text-gray-500 dark:tw-text-gray-500 tw-mt-0.5\">{{ getTimeAgo(notif.timestamp) }}</p>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-flex-shrink-0\">\n @if (!isNotificationRead(notif)) {\n <div class=\"tw-w-1.5 tw-h-1.5 tw-rounded-full tw-bg-blue-500 dark:tw-bg-blue-400 tw-animate-pulse\"></div>\n }\n @if (isNotificationAnimating(notif) && isNotificationUndoable(notif)) {\n <button \n type=\"button\"\n (click)=\"undoNotificationRemoval(getNotificationId(notif)); $event.stopPropagation()\"\n class=\"tw-px-2 tw-py-0.5 tw-text-[9px] tw-font-semibold tw-text-blue-600 dark:tw-text-blue-400 tw-bg-blue-50 dark:tw-bg-blue-900 tw-border tw-border-blue-200 dark:tw-border-blue-700 tw-rounded-md tw-cursor-pointer tw-transition-all tw-duration-200 hover:tw-bg-blue-100 dark:hover:tw-bg-blue-800 hover:tw-border-blue-300 dark:hover:tw-border-blue-600 hover:tw-scale-105 tw-whitespace-nowrap tw-animate-pulse\">\n Undo\n </button>\n }\n </div>\n </div>\n \n <!-- Message -->\n @if (notif.message && notif.message !== notif.title) {\n <p class=\"tw-m-0 tw-mt-1 tw-text-[10px] tw-text-gray-700 dark:tw-text-gray-400 tw-leading-snug tw-line-clamp-2\">\n {{ notif.message }}\n </p>\n }\n \n <!-- Comment -->\n @if (notif.data?.comment) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-100 dark:tw-bg-gray-700 tw-rounded-md tw-border-l-2 tw-border-l-blue-500 dark:tw-border-l-blue-500\">\n <p class=\"tw-m-0 tw-text-[10px] tw-text-gray-800 dark:tw-text-gray-300 tw-leading-snug tw-italic tw-line-clamp-2\">{{ notif.data.comment }}</p>\n </div>\n }\n \n <!-- File -->\n @if (notif.data?.file) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-100 dark:tw-bg-gray-700 tw-border tw-border-gray-300 dark:tw-border-gray-600 tw-rounded-md tw-flex tw-items-center tw-gap-2\">\n <div class=\"tw-w-7 tw-h-7 tw-bg-blue-100 dark:tw-bg-blue-900 tw-rounded-md tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\n <span class=\"tw-text-[9px] tw-font-bold tw-text-blue-700 dark:tw-text-blue-300\">{{ getFileIcon(notif.data.file.type) }}</span>\n </div>\n <div class=\"tw-flex-1 tw-min-w-0\">\n <p class=\"tw-m-0 tw-text-[10px] tw-font-semibold tw-text-gray-900 dark:tw-text-gray-100 tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap\">{{ notif.data.file.name }}</p>\n <p class=\"tw-m-0 tw-text-[9px] tw-text-gray-600 dark:tw-text-gray-400\">{{ notif.data.file.size }}</p>\n </div>\n <cide-ele-icon class=\"!tw-text-sm !tw-text-blue-600 dark:!tw-text-blue-400 tw-cursor-pointer tw-transition-all tw-duration-200 tw-flex-shrink-0 hover:tw-text-blue-700 dark:hover:tw-text-blue-300 hover:tw-scale-110\">download</cide-ele-icon>\n </div>\n }\n \n <!-- Action Buttons -->\n @if (notif.action_label) {\n <div class=\"tw-mt-1.5 tw-flex tw-gap-1.5\">\n @if (notif.action_label.toLowerCase().includes('decline')) {\n <button type=\"button\" class=\"tw-py-1 tw-px-3 tw-border tw-border-gray-300 dark:tw-border-gray-600 tw-bg-white dark:tw-bg-gray-800 tw-rounded-md tw-text-[10px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-800 dark:tw-text-gray-300 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-700 hover:tw-border-gray-400 dark:hover:tw-border-gray-500 hover:tw-scale-105\">Decline</button>\n }\n @if (notif.action_label.toLowerCase().includes('accept')) {\n <button type=\"button\" class=\"tw-py-1 tw-px-3 tw-border tw-border-blue-600 dark:tw-border-blue-500 tw-bg-blue-600 dark:tw-bg-blue-500 tw-rounded-md tw-text-[10px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-white hover:tw-bg-blue-700 dark:hover:tw-bg-blue-600 hover:tw-border-blue-700 dark:hover:tw-border-blue-600 hover:tw-scale-105\">Accept</button>\n }\n </div>\n }\n </div>\n </div>\n }\n }\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,rgb(var(--tw-white-rgb) / .95),rgb(var(--tw-gray-50-rgb) / .95));box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:200;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgb(var(--tw-gray-200-rgb) / .8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-sidebar-toggle{display:flex;align-items:center;justify-content:center;border:none;background:transparent;outline:none;transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;flex-shrink:0}.header-sidebar-toggle:hover{background-color:rgb(var(--tw-gray-100-rgb) / .8);transform:scale(1.08)}.header-sidebar-toggle:active{transform:scale(.92);transition:transform .15s cubic-bezier(.4,0,.2,1)}.header-sidebar-toggle:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:.5rem}.header-sidebar-toggle cide-ele-icon{transition:transform .4s cubic-bezier(.4,0,.2,1),opacity .3s cubic-bezier(.4,0,.2,1);display:inline-block;transform-origin:center}.header-sidebar-toggle:hover cide-ele-icon{transform:scale(1.15) rotate(5deg)}.header-sidebar-toggle.animating cide-ele-icon{animation:iconRotate .4s cubic-bezier(.4,0,.2,1)}@keyframes iconRotate{0%{transform:rotate(0) scale(1);opacity:.8}50%{transform:rotate(180deg) scale(1.15);opacity:1}to{transform:rotate(360deg) scale(1);opacity:1}}.header-sidebar-toggle cide-ele-icon{transition:transform .4s cubic-bezier(.4,0,.2,1),opacity .3s cubic-bezier(.4,0,.2,1),color .3s cubic-bezier(.4,0,.2,1);display:inline-block;transform-origin:center}.header-sidebar-toggle.animating cide-ele-icon{animation:iconFadeRotate .4s cubic-bezier(.4,0,.2,1)}@keyframes iconFadeRotate{0%{opacity:1;transform:scale(1) rotate(0)}50%{opacity:.3;transform:scale(.8) rotate(180deg)}to{opacity:1;transform:scale(1) rotate(360deg)}}:root[data-theme=dark] .header-sidebar-toggle,:root.dark-mode .header-sidebar-toggle{color:var(--cide-theme-text-color)}:root[data-theme=dark] .header-sidebar-toggle:hover,:root.dark-mode .header-sidebar-toggle:hover{background-color:var(--cide-theme-hover-bg-color);color:var(--cide-theme-color-brand-primary)}.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,rgb(var(--tw-white-rgb) / 0),rgb(var(--tw-white-rgb) / .3),rgb(var(--tw-white-rgb) / 0));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:rgb(var(--tw-gray-50-rgb) / .8);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:rgb(var(--tw-white-rgb) / 1);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:rgb(var(--tw-gray-700-rgb) / .9);color:rgb(var(--tw-white-rgb) / 1);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:-2px;right:-2px;min-width:18px;height:18px;border-radius:9px;background-color:#ef4444;color:rgb(var(--tw-white-rgb) / 1);font-size:10px;display:flex!important;align-items:center;justify-content:center;padding:0 5px;box-shadow:0 2px 4px #ef444466;font-weight:700;z-index:10;transition:all .2s ease;line-height:1;border:2px solid #ffffff}.header-icon:hover .header-badge{transform:scale(1.15);box-shadow:0 3px 6px #ef444480}.header-icon.notification-icon{position:relative;overflow:visible}.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:rgb(var(--tw-white-rgb) / 1);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}:root[data-theme=dark] .cide-lyt-header,:root.dark-mode .cide-lyt-header{background:linear-gradient(to right,var(--cide-theme-light-color),var(--cide-theme-hover-bg-color));border-bottom-color:var(--cide-theme-border-color);box-shadow:0 2px 8px var(--cide-theme-shadow-color)}:root[data-theme=dark] .header-icon,:root.dark-mode .header-icon{color:var(--cide-theme-text-color)}:root[data-theme=dark] .header-icon.notification-icon,:root.dark-mode .header-icon.notification-icon{color:#d1d5db}:root[data-theme=dark] .header-icon.notification-icon:hover,:root.dark-mode .header-icon.notification-icon:hover{color:#60a5fa}:root[data-theme=dark] .header-divider,:root.dark-mode .header-divider{background-color:var(--cide-theme-border-color)}:root[data-theme=dark] .header-year-pill,:root.dark-mode .header-year-pill{background:linear-gradient(135deg,#60a5fa33,#3b82f640);border-color:#60a5fa80;color:#60a5fa}:root[data-theme=dark] .header-year-pill .header-year-pill-text,:root.dark-mode .header-year-pill .header-year-pill-text{color:#60a5fa}:root[data-theme=dark] .header-year-pill cide-ele-icon,:root.dark-mode .header-year-pill cide-ele-icon{color:#60a5fa!important}:root[data-theme=dark] .header-year-pill:hover,:root.dark-mode .header-year-pill:hover{background:linear-gradient(135deg,#60a5fa4d,#3b82f659);border-color:#60a5fa99;color:#93c5fd}:root[data-theme=dark] .header-year-pill:hover .header-year-pill-text,:root.dark-mode .header-year-pill:hover .header-year-pill-text{color:#93c5fd}:root[data-theme=dark] .header-year-pill:hover cide-ele-icon,:root.dark-mode .header-year-pill:hover cide-ele-icon{color:#93c5fd!important}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search{background-color:var(--cide-theme-hover-bg-color);border-color:var(--cide-theme-border-color)}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search:hover,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search:hover{background-color:var(--cide-theme-light-color);box-shadow:0 3px 12px var(--cide-theme-shadow-color)}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:var(--cide-theme-label-color)!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){.cide-lyt-header{padding:.5rem .75rem;flex-wrap:wrap;min-height:56px;height:auto}.header-logo-container{padding:.25rem 0}.header-logo-container img,.header-logo-container cide-ele-icon{width:24px;height:24px}.header-logo-container+span{font-size:.875rem;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header-search-container{order:3;flex:1 1 100%;max-width:100%;margin:.5rem 0 0;min-width:0}@media (max-width: 480px){.header-search-container{display:none}}.header-icons-container{gap:.5rem;flex-wrap:wrap;justify-content:flex-end}.header-icon{width:28px;height:28px;margin:0 1px}.header-year-pill{padding:.2rem .5rem;font-size:.625rem;min-height:20px;height:20px}.header-year-pill-text{max-width:80px}.profile-avatar{width:24px;height:24px;font-size:.625rem}.header-divider{display:none}.header-dropdown-container{margin:0 1px}.header-badge{min-width:16px;height:16px;font-size:9px;top:-1px;right:-1px}}@media (max-width: 640px){.cide-lyt-header{padding:.5rem}.header-search-container{max-width:100%;margin:.5rem 0 0}.header-icon{width:26px;height:26px}@media (max-width: 480px){.header-year-pill-text{display:none}.header-year-pill{padding:.2rem;width:28px;justify-content:center}.header-icons-container{gap:.25rem}}}@media (min-width: 769px) and (max-width: 1024px){.header-search-container{max-width:400px;margin:0 1.5rem}.header-icons-container{gap:.75rem}}@media (max-width: 768px) and (orientation: landscape){.cide-lyt-header{min-height:48px;padding:.375rem .75rem}.header-search-container{order:0;flex:0 1 auto;max-width:250px;margin:0 1rem}}.notification-scroll-container{scrollbar-width:thin;scrollbar-color:var(--cide-ele-scrollbar-thumb, #d1d5db) var(--cide-ele-scrollbar-track, transparent)}.notification-scroll-container::-webkit-scrollbar{width:6px;height:6px}.notification-scroll-container::-webkit-scrollbar-track{background:var(--cide-ele-scrollbar-track, transparent)}.notification-scroll-container::-webkit-scrollbar-thumb{background-color:var(--cide-ele-scrollbar-thumb, #d1d5db);border-radius:3px}.notification-scroll-container::-webkit-scrollbar-thumb:hover{background-color:var(--cide-ele-scrollbar-thumb-hover, #9ca3af)}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container{background-color:#fff!important;color:#111827!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container *{color:inherit}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-900{color:#111827!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-800{color:#1f2937!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-700{color:#374151!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-600{color:#4b5563!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-500{color:#6b7280!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-blue-600{color:#2563eb!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-white{background-color:#fff!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-gray-50{background-color:#f9fafb!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-gray-100{background-color:#f3f4f6!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-blue-50{background-color:#eff6ff!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", "step", "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"] }] });
|
|
3618
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", 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 }, { propertyName: "notificationDropdown", first: true, predicate: ["notificationDropdown"], 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 <!-- Sidebar Toggle Button - Only visible when sidebar is visible -->\n @if (isSidebarVisible()) {\n <button \n class=\"header-sidebar-toggle tw-flex tw-items-center tw-justify-center tw-w-10 tw-h-10 tw-rounded-lg tw-text-gray-600 hover:tw-text-gray-900 hover:tw-bg-gray-100 tw-transition-all tw-duration-300 tw-cursor-pointer tw-mr-1\"\n (click)=\"toggleSidebar()\"\n (keydown.enter)=\"toggleSidebar()\"\n (keydown.space)=\"toggleSidebar()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"isSidebarCollapsed() ? 'Expand sidebar menu' : 'Collapse sidebar menu'\"\n [attr.title]=\"isSidebarCollapsed() ? 'Expand sidebar menu' : 'Collapse sidebar menu'\">\n <cide-ele-icon size=\"md\" type=\"none\">\n {{ isSidebarCollapsed() ? 'menu' : 'menu_open' }}\n </cide-ele-icon>\n </button>\n }\n \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 #notificationDropdown\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=\"tw-min-w-[380px] tw-bg-white dark:tw-bg-gray-800 tw-rounded-xl tw-shadow-2xl tw-overflow-hidden tw-text-gray-900 dark:tw-text-gray-100\">\n <!-- Header - Fixed/Sticky -->\n <div class=\"tw-sticky tw-top-0 tw-z-10 tw-px-2.5 tw-py-1 tw-bg-white dark:tw-bg-gray-800 tw-flex tw-justify-between tw-items-center tw-border-b tw-border-gray-200 dark:tw-border-gray-700 tw-backdrop-blur-sm\">\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <div class=\"tw-w-5 tw-h-5 tw-bg-blue-500 tw-rounded tw-flex tw-items-center tw-justify-center tw-shadow-sm\">\n <cide-ele-icon class=\"!tw-text-[10px] !tw-text-white\">notifications</cide-ele-icon>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <h3 class=\"tw-m-0 tw-text-[10px] tw-font-bold tw-text-gray-900 dark:tw-text-gray-100 tw-leading-none\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"tw-bg-red-500 tw-text-white tw-px-1 tw-py-0 tw-rounded-full tw-text-[7px] tw-font-bold tw-leading-none tw-animate-pulse\">{{ unreadCount() }}</span>\n }\n </div>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-0.5\">\n <button \n type=\"button\"\n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-600 dark:tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-200 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-600 hover:tw-text-gray-900 dark:hover:tw-text-gray-200\"\n (click)=\"openNotificationSettings(); $event.stopPropagation()\"\n title=\"Notification Settings\">\n <cide-ele-icon class=\"!tw-text-xs\">settings</cide-ele-icon>\n </button>\n @if (unreadCount() > 0) {\n <button \n type=\"button\"\n class=\"tw-bg-blue-500 tw-text-white tw-px-1 tw-py-0.5 tw-rounded tw-text-[8px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-flex tw-items-center tw-gap-0.5 tw-shadow-sm hover:tw-bg-blue-600 hover:tw-scale-105\"\n (click)=\"markAllAsRead(); $event.stopPropagation()\"\n title=\"Mark all as read\">\n <cide-ele-icon class=\"!tw-text-[9px]\">done_all</cide-ele-icon>\n </button>\n }\n <button \n type=\"button\" \n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-600 dark:tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-200 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-600 hover:tw-text-gray-900 dark:hover:tw-text-gray-200 hover:tw-rotate-90\"\n (click)=\"closeNotificationDropdown($event)\"\n title=\"Close\">\n <cide-ele-icon class=\"!tw-text-xs\">close</cide-ele-icon>\n </button>\n </div>\n </div>\n\n <!-- Notifications List -->\n <div class=\"tw-overflow-x-hidden notification-scroll-container tw-bg-white dark:tw-bg-gray-800 tw-text-gray-900 dark:tw-text-gray-100\">\n @if (notifications().length === 0) {\n <div class=\"tw-py-16 tw-px-4 tw-text-center tw-bg-white dark:tw-bg-gray-800\">\n <cide-ele-icon class=\"!tw-text-6xl !tw-text-gray-300 dark:!tw-text-gray-600 tw-mb-3\">notifications_off</cide-ele-icon>\n <p class=\"tw-m-0 tw-text-sm tw-text-gray-600 dark:tw-text-gray-400 tw-font-medium\">No notifications yet</p>\n <p class=\"tw-m-0 tw-mt-1 tw-text-xs tw-text-gray-500 dark:tw-text-gray-500\">You're all caught up!</p>\n </div>\n } @else {\n @for (notif of notifications().slice(0, 15); track notif.id) {\n <div \n class=\"tw-flex tw-items-start tw-px-3 tw-py-2 tw-cursor-pointer tw-transition-all tw-duration-300 tw-relative tw-gap-2 tw-border-b tw-border-gray-200 dark:tw-border-gray-700 last:tw-border-b-0 hover:tw-bg-gray-50 dark:hover:tw-bg-gray-700 tw-transform tw-ease-in-out tw-bg-white dark:tw-bg-gray-800 tw-text-gray-900 dark:tw-text-gray-100\"\n [class.tw-border-l-2]=\"!isNotificationRead(notif)\"\n [class.tw-border-l-blue-500]=\"!isNotificationRead(notif)\"\n [class.dark:tw-border-l-blue-400]=\"!isNotificationRead(notif)\"\n [class.tw-bg-blue-50]=\"!isNotificationRead(notif)\"\n [class.dark:tw-bg-gray-700]=\"!isNotificationRead(notif)\"\n [class.-tw-translate-x-full]=\"isNotificationAnimating(notif)\"\n [class.tw-opacity-0]=\"isNotificationAnimating(notif)\"\n [class.tw-max-h-0]=\"isNotificationAnimating(notif)\"\n [class.tw-overflow-hidden]=\"isNotificationAnimating(notif)\"\n [class.tw-mb-0]=\"isNotificationAnimating(notif)\"\n [class.tw-p-0]=\"isNotificationAnimating(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <!-- Icon/Avatar -->\n <div class=\"tw-flex-shrink-0 tw-relative\">\n <div class=\"tw-w-9 tw-h-9 tw-rounded-full tw-overflow-hidden tw-bg-gradient-to-br tw-from-blue-500 tw-to-blue-600 tw-flex tw-items-center tw-justify-center tw-shadow-sm tw-ring-1 tw-ring-white\">\n @if (getNotificationAvatar(notif)) {\n <img \n cideEleFileImage \n [fileId]=\"getNotificationAvatar(notif) || ''\"\n [altText]=\"getNotificationName(notif)\"\n class=\"tw-w-full tw-h-full tw-object-cover\">\n } @else {\n <cide-ele-icon class=\"!tw-text-base !tw-text-white\">{{ getNotificationIcon(notif.type) }}</cide-ele-icon>\n }\n </div>\n <!-- Green online indicator -->\n <div class=\"tw-absolute tw-bottom-0 tw-right-0 tw-w-2 tw-h-2 tw-bg-green-500 tw-rounded-full tw-border tw-border-white\"></div>\n </div>\n\n <!-- Content -->\n <div class=\"tw-flex-1 tw-min-w-0\">\n <!-- Title and relative time -->\n <div class=\"tw-flex tw-items-start tw-justify-between tw-gap-1.5 tw-mb-0.5\">\n <div class=\"tw-flex-1 tw-min-w-0\">\n <h4 class=\"tw-m-0 tw-text-[11px] tw-font-bold tw-text-gray-900 dark:tw-text-gray-100 tw-leading-tight\">\n <span class=\"tw-text-blue-600 dark:tw-text-blue-400\">{{ getNotificationName(notif) }}</span><span class=\"tw-font-normal tw-text-gray-800 dark:tw-text-gray-300\"> {{ getNotificationAction(notif) }}</span>\n </h4>\n <p class=\"tw-m-0 tw-text-[9px] tw-text-gray-500 dark:tw-text-gray-500 tw-mt-0.5\">{{ getTimeAgo(notif.timestamp) }}</p>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-flex-shrink-0\">\n @if (!isNotificationRead(notif)) {\n <div class=\"tw-w-1.5 tw-h-1.5 tw-rounded-full tw-bg-blue-500 dark:tw-bg-blue-400 tw-animate-pulse\"></div>\n }\n @if (isNotificationAnimating(notif) && isNotificationUndoable(notif)) {\n <button \n type=\"button\"\n (click)=\"undoNotificationRemoval(getNotificationId(notif)); $event.stopPropagation()\"\n class=\"tw-px-2 tw-py-0.5 tw-text-[9px] tw-font-semibold tw-text-blue-600 dark:tw-text-blue-400 tw-bg-blue-50 dark:tw-bg-blue-900 tw-border tw-border-blue-200 dark:tw-border-blue-700 tw-rounded-md tw-cursor-pointer tw-transition-all tw-duration-200 hover:tw-bg-blue-100 dark:hover:tw-bg-blue-800 hover:tw-border-blue-300 dark:hover:tw-border-blue-600 hover:tw-scale-105 tw-whitespace-nowrap tw-animate-pulse\">\n Undo\n </button>\n }\n </div>\n </div>\n \n <!-- Message -->\n @if (notif.message && notif.message !== notif.title) {\n <p class=\"tw-m-0 tw-mt-1 tw-text-[10px] tw-text-gray-700 dark:tw-text-gray-400 tw-leading-snug tw-line-clamp-2\">\n {{ notif.message }}\n </p>\n }\n \n <!-- Comment -->\n @if (notif.data?.comment) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-100 dark:tw-bg-gray-700 tw-rounded-md tw-border-l-2 tw-border-l-blue-500 dark:tw-border-l-blue-500\">\n <p class=\"tw-m-0 tw-text-[10px] tw-text-gray-800 dark:tw-text-gray-300 tw-leading-snug tw-italic tw-line-clamp-2\">{{ notif.data.comment }}</p>\n </div>\n }\n \n <!-- File -->\n @if (notif.data?.file) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-100 dark:tw-bg-gray-700 tw-border tw-border-gray-300 dark:tw-border-gray-600 tw-rounded-md tw-flex tw-items-center tw-gap-2\">\n <div class=\"tw-w-7 tw-h-7 tw-bg-blue-100 dark:tw-bg-blue-900 tw-rounded-md tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\n <span class=\"tw-text-[9px] tw-font-bold tw-text-blue-700 dark:tw-text-blue-300\">{{ getFileIcon(notif.data.file.type) }}</span>\n </div>\n <div class=\"tw-flex-1 tw-min-w-0\">\n <p class=\"tw-m-0 tw-text-[10px] tw-font-semibold tw-text-gray-900 dark:tw-text-gray-100 tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap\">{{ notif.data.file.name }}</p>\n <p class=\"tw-m-0 tw-text-[9px] tw-text-gray-600 dark:tw-text-gray-400\">{{ notif.data.file.size }}</p>\n </div>\n <cide-ele-icon class=\"!tw-text-sm !tw-text-blue-600 dark:!tw-text-blue-400 tw-cursor-pointer tw-transition-all tw-duration-200 tw-flex-shrink-0 hover:tw-text-blue-700 dark:hover:tw-text-blue-300 hover:tw-scale-110\">download</cide-ele-icon>\n </div>\n }\n \n <!-- Action Buttons -->\n @if (notif.action_label) {\n <div class=\"tw-mt-1.5 tw-flex tw-gap-1.5\">\n @if (notif.action_label.toLowerCase().includes('decline')) {\n <button type=\"button\" class=\"tw-py-1 tw-px-3 tw-border tw-border-gray-300 dark:tw-border-gray-600 tw-bg-white dark:tw-bg-gray-800 tw-rounded-md tw-text-[10px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-800 dark:tw-text-gray-300 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-700 hover:tw-border-gray-400 dark:hover:tw-border-gray-500 hover:tw-scale-105\">Decline</button>\n }\n @if (notif.action_label.toLowerCase().includes('accept')) {\n <button type=\"button\" class=\"tw-py-1 tw-px-3 tw-border tw-border-blue-600 dark:tw-border-blue-500 tw-bg-blue-600 dark:tw-bg-blue-500 tw-rounded-md tw-text-[10px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-white hover:tw-bg-blue-700 dark:hover:tw-bg-blue-600 hover:tw-border-blue-700 dark:hover:tw-border-blue-600 hover:tw-scale-105\">Accept</button>\n }\n </div>\n }\n </div>\n </div>\n }\n }\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,rgb(var(--tw-white-rgb) / .95),rgb(var(--tw-gray-50-rgb) / .95));box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:200;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgb(var(--tw-gray-200-rgb) / .8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-sidebar-toggle{display:flex;align-items:center;justify-content:center;border:none;background:transparent;outline:none;transition:background-color .2s ease;position:relative;flex-shrink:0}.header-sidebar-toggle:hover{background-color:rgb(var(--tw-gray-100-rgb) / .8)}.header-sidebar-toggle:active{background-color:rgb(var(--tw-gray-200-rgb) / .8)}.header-sidebar-toggle:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:.5rem}.header-sidebar-toggle cide-ele-icon{transition:transform .2s ease,opacity .2s ease;display:inline-block;transform-origin:center}.header-sidebar-toggle:hover cide-ele-icon{transform:scale(1.1)}:root[data-theme=dark] .header-sidebar-toggle,:root.dark-mode .header-sidebar-toggle{color:var(--cide-theme-text-color)}:root[data-theme=dark] .header-sidebar-toggle:hover,:root.dark-mode .header-sidebar-toggle:hover{background-color:var(--cide-theme-hover-bg-color);color:var(--cide-theme-color-brand-primary)}.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,rgb(var(--tw-white-rgb) / 0),rgb(var(--tw-white-rgb) / .3),rgb(var(--tw-white-rgb) / 0));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:rgb(var(--tw-gray-50-rgb) / .8);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:rgb(var(--tw-white-rgb) / 1);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:rgb(var(--tw-gray-700-rgb) / .9);color:rgb(var(--tw-white-rgb) / 1);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:-2px;right:-2px;min-width:18px;height:18px;border-radius:9px;background-color:#ef4444;color:rgb(var(--tw-white-rgb) / 1);font-size:10px;display:flex!important;align-items:center;justify-content:center;padding:0 5px;box-shadow:0 2px 4px #ef444466;font-weight:700;z-index:10;transition:all .2s ease;line-height:1;border:2px solid #ffffff}.header-icon:hover .header-badge{transform:scale(1.15);box-shadow:0 3px 6px #ef444480}.header-icon.notification-icon{position:relative;overflow:visible}.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:rgb(var(--tw-white-rgb) / 1);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}:root[data-theme=dark] .cide-lyt-header,:root.dark-mode .cide-lyt-header{background:linear-gradient(to right,var(--cide-theme-light-color),var(--cide-theme-hover-bg-color));border-bottom-color:var(--cide-theme-border-color);box-shadow:0 2px 8px var(--cide-theme-shadow-color)}:root[data-theme=dark] .header-icon,:root.dark-mode .header-icon{color:var(--cide-theme-text-color)}:root[data-theme=dark] .header-icon.notification-icon,:root.dark-mode .header-icon.notification-icon{color:#d1d5db}:root[data-theme=dark] .header-icon.notification-icon:hover,:root.dark-mode .header-icon.notification-icon:hover{color:#60a5fa}:root[data-theme=dark] .header-divider,:root.dark-mode .header-divider{background-color:var(--cide-theme-border-color)}:root[data-theme=dark] .header-year-pill,:root.dark-mode .header-year-pill{background:linear-gradient(135deg,#60a5fa33,#3b82f640);border-color:#60a5fa80;color:#60a5fa}:root[data-theme=dark] .header-year-pill .header-year-pill-text,:root.dark-mode .header-year-pill .header-year-pill-text{color:#60a5fa}:root[data-theme=dark] .header-year-pill cide-ele-icon,:root.dark-mode .header-year-pill cide-ele-icon{color:#60a5fa!important}:root[data-theme=dark] .header-year-pill:hover,:root.dark-mode .header-year-pill:hover{background:linear-gradient(135deg,#60a5fa4d,#3b82f659);border-color:#60a5fa99;color:#93c5fd}:root[data-theme=dark] .header-year-pill:hover .header-year-pill-text,:root.dark-mode .header-year-pill:hover .header-year-pill-text{color:#93c5fd}:root[data-theme=dark] .header-year-pill:hover cide-ele-icon,:root.dark-mode .header-year-pill:hover cide-ele-icon{color:#93c5fd!important}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search{background-color:var(--cide-theme-hover-bg-color);border-color:var(--cide-theme-border-color)}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search:hover,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search:hover{background-color:var(--cide-theme-light-color);box-shadow:0 3px 12px var(--cide-theme-shadow-color)}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:var(--cide-theme-label-color)!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){.cide-lyt-header{padding:.5rem .75rem;flex-wrap:wrap;min-height:56px;height:auto}.header-logo-container{padding:.25rem 0}.header-logo-container img,.header-logo-container cide-ele-icon{width:24px;height:24px}.header-logo-container+span{font-size:.875rem;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header-search-container{order:3;flex:1 1 100%;max-width:100%;margin:.5rem 0 0;min-width:0}@media (max-width: 480px){.header-search-container{display:none}}.header-icons-container{gap:.5rem;flex-wrap:wrap;justify-content:flex-end}.header-icon{width:28px;height:28px;margin:0 1px}.header-year-pill{padding:.2rem .5rem;font-size:.625rem;min-height:20px;height:20px}.header-year-pill-text{max-width:80px}.profile-avatar{width:24px;height:24px;font-size:.625rem}.header-divider{display:none}.header-dropdown-container{margin:0 1px}.header-badge{min-width:16px;height:16px;font-size:9px;top:-1px;right:-1px}}@media (max-width: 640px){.cide-lyt-header{padding:.5rem}.header-search-container{max-width:100%;margin:.5rem 0 0}.header-icon{width:26px;height:26px}@media (max-width: 480px){.header-year-pill-text{display:none}.header-year-pill{padding:.2rem;width:28px;justify-content:center}.header-icons-container{gap:.25rem}}}@media (min-width: 769px) and (max-width: 1024px){.header-search-container{max-width:400px;margin:0 1.5rem}.header-icons-container{gap:.75rem}}@media (max-width: 768px) and (orientation: landscape){.cide-lyt-header{min-height:48px;padding:.375rem .75rem}.header-search-container{order:0;flex:0 1 auto;max-width:250px;margin:0 1rem}}.notification-scroll-container{scrollbar-width:thin;scrollbar-color:var(--cide-ele-scrollbar-thumb, #d1d5db) var(--cide-ele-scrollbar-track, transparent)}.notification-scroll-container::-webkit-scrollbar{width:6px;height:6px}.notification-scroll-container::-webkit-scrollbar-track{background:var(--cide-ele-scrollbar-track, transparent)}.notification-scroll-container::-webkit-scrollbar-thumb{background-color:var(--cide-ele-scrollbar-thumb, #d1d5db);border-radius:3px}.notification-scroll-container::-webkit-scrollbar-thumb:hover{background-color:var(--cide-ele-scrollbar-thumb-hover, #9ca3af)}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container{background-color:#fff!important;color:#111827!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container *{color:inherit}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-900{color:#111827!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-800{color:#1f2937!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-700{color:#374151!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-600{color:#4b5563!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-500{color:#6b7280!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-blue-600{color:#2563eb!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-white{background-color:#fff!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-gray-50{background-color:#f9fafb!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-gray-100{background-color:#f3f4f6!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-blue-50{background-color:#eff6ff!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", "step", "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"] }] });
|
|
3595
3619
|
}
|
|
3596
3620
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideLytHeaderWrapperComponent, decorators: [{
|
|
3597
3621
|
type: Component,
|
|
3598
3622
|
args: [{ selector: 'cide-lyt-header-wrapper', imports: [CideInputComponent, CommonModule, CideIconComponent,
|
|
3599
|
-
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 <!-- Sidebar Toggle Button - Always visible -->\n <button \n class=\"header-sidebar-toggle tw-flex tw-items-center tw-justify-center tw-w-10 tw-h-10 tw-rounded-lg tw-text-gray-600 hover:tw-text-gray-900 hover:tw-bg-gray-100 tw-transition-all tw-duration-300 tw-cursor-pointer tw-mr-1\"\n (click)=\"toggleSidebar()\"\n (keydown.enter)=\"toggleSidebar()\"\n (keydown.space)=\"toggleSidebar()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"isSidebarCollapsed() ? 'Expand sidebar menu' : 'Collapse sidebar menu'\"\n [attr.title]=\"isSidebarCollapsed() ? 'Expand sidebar menu' : 'Collapse sidebar menu'\">\n <cide-ele-icon size=\"md\" type=\"none\">\n {{ isSidebarCollapsed() ? 'menu' : 'menu_open' }}\n </cide-ele-icon>\n </button>\n \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 #notificationDropdown\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=\"tw-min-w-[380px] tw-bg-white dark:tw-bg-gray-800 tw-rounded-xl tw-shadow-2xl tw-overflow-hidden tw-text-gray-900 dark:tw-text-gray-100\">\n <!-- Header - Fixed/Sticky -->\n <div class=\"tw-sticky tw-top-0 tw-z-10 tw-px-2.5 tw-py-1 tw-bg-white dark:tw-bg-gray-800 tw-flex tw-justify-between tw-items-center tw-border-b tw-border-gray-200 dark:tw-border-gray-700 tw-backdrop-blur-sm\">\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <div class=\"tw-w-5 tw-h-5 tw-bg-blue-500 tw-rounded tw-flex tw-items-center tw-justify-center tw-shadow-sm\">\n <cide-ele-icon class=\"!tw-text-[10px] !tw-text-white\">notifications</cide-ele-icon>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <h3 class=\"tw-m-0 tw-text-[10px] tw-font-bold tw-text-gray-900 dark:tw-text-gray-100 tw-leading-none\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"tw-bg-red-500 tw-text-white tw-px-1 tw-py-0 tw-rounded-full tw-text-[7px] tw-font-bold tw-leading-none tw-animate-pulse\">{{ unreadCount() }}</span>\n }\n </div>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-0.5\">\n <button \n type=\"button\"\n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-600 dark:tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-200 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-600 hover:tw-text-gray-900 dark:hover:tw-text-gray-200\"\n (click)=\"openNotificationSettings(); $event.stopPropagation()\"\n title=\"Notification Settings\">\n <cide-ele-icon class=\"!tw-text-xs\">settings</cide-ele-icon>\n </button>\n @if (unreadCount() > 0) {\n <button \n type=\"button\"\n class=\"tw-bg-blue-500 tw-text-white tw-px-1 tw-py-0.5 tw-rounded tw-text-[8px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-flex tw-items-center tw-gap-0.5 tw-shadow-sm hover:tw-bg-blue-600 hover:tw-scale-105\"\n (click)=\"markAllAsRead(); $event.stopPropagation()\"\n title=\"Mark all as read\">\n <cide-ele-icon class=\"!tw-text-[9px]\">done_all</cide-ele-icon>\n </button>\n }\n <button \n type=\"button\" \n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-600 dark:tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-200 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-600 hover:tw-text-gray-900 dark:hover:tw-text-gray-200 hover:tw-rotate-90\"\n (click)=\"closeNotificationDropdown($event)\"\n title=\"Close\">\n <cide-ele-icon class=\"!tw-text-xs\">close</cide-ele-icon>\n </button>\n </div>\n </div>\n\n <!-- Notifications List -->\n <div class=\"tw-overflow-x-hidden notification-scroll-container tw-bg-white dark:tw-bg-gray-800 tw-text-gray-900 dark:tw-text-gray-100\">\n @if (notifications().length === 0) {\n <div class=\"tw-py-16 tw-px-4 tw-text-center tw-bg-white dark:tw-bg-gray-800\">\n <cide-ele-icon class=\"!tw-text-6xl !tw-text-gray-300 dark:!tw-text-gray-600 tw-mb-3\">notifications_off</cide-ele-icon>\n <p class=\"tw-m-0 tw-text-sm tw-text-gray-600 dark:tw-text-gray-400 tw-font-medium\">No notifications yet</p>\n <p class=\"tw-m-0 tw-mt-1 tw-text-xs tw-text-gray-500 dark:tw-text-gray-500\">You're all caught up!</p>\n </div>\n } @else {\n @for (notif of notifications().slice(0, 15); track notif.id) {\n <div \n class=\"tw-flex tw-items-start tw-px-3 tw-py-2 tw-cursor-pointer tw-transition-all tw-duration-300 tw-relative tw-gap-2 tw-border-b tw-border-gray-200 dark:tw-border-gray-700 last:tw-border-b-0 hover:tw-bg-gray-50 dark:hover:tw-bg-gray-700 tw-transform tw-ease-in-out tw-bg-white dark:tw-bg-gray-800 tw-text-gray-900 dark:tw-text-gray-100\"\n [class.tw-border-l-2]=\"!isNotificationRead(notif)\"\n [class.tw-border-l-blue-500]=\"!isNotificationRead(notif)\"\n [class.dark:tw-border-l-blue-400]=\"!isNotificationRead(notif)\"\n [class.tw-bg-blue-50]=\"!isNotificationRead(notif)\"\n [class.dark:tw-bg-gray-700]=\"!isNotificationRead(notif)\"\n [class.-tw-translate-x-full]=\"isNotificationAnimating(notif)\"\n [class.tw-opacity-0]=\"isNotificationAnimating(notif)\"\n [class.tw-max-h-0]=\"isNotificationAnimating(notif)\"\n [class.tw-overflow-hidden]=\"isNotificationAnimating(notif)\"\n [class.tw-mb-0]=\"isNotificationAnimating(notif)\"\n [class.tw-p-0]=\"isNotificationAnimating(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <!-- Icon/Avatar -->\n <div class=\"tw-flex-shrink-0 tw-relative\">\n <div class=\"tw-w-9 tw-h-9 tw-rounded-full tw-overflow-hidden tw-bg-gradient-to-br tw-from-blue-500 tw-to-blue-600 tw-flex tw-items-center tw-justify-center tw-shadow-sm tw-ring-1 tw-ring-white\">\n @if (getNotificationAvatar(notif)) {\n <img \n cideEleFileImage \n [fileId]=\"getNotificationAvatar(notif) || ''\"\n [altText]=\"getNotificationName(notif)\"\n class=\"tw-w-full tw-h-full tw-object-cover\">\n } @else {\n <cide-ele-icon class=\"!tw-text-base !tw-text-white\">{{ getNotificationIcon(notif.type) }}</cide-ele-icon>\n }\n </div>\n <!-- Green online indicator -->\n <div class=\"tw-absolute tw-bottom-0 tw-right-0 tw-w-2 tw-h-2 tw-bg-green-500 tw-rounded-full tw-border tw-border-white\"></div>\n </div>\n\n <!-- Content -->\n <div class=\"tw-flex-1 tw-min-w-0\">\n <!-- Title and relative time -->\n <div class=\"tw-flex tw-items-start tw-justify-between tw-gap-1.5 tw-mb-0.5\">\n <div class=\"tw-flex-1 tw-min-w-0\">\n <h4 class=\"tw-m-0 tw-text-[11px] tw-font-bold tw-text-gray-900 dark:tw-text-gray-100 tw-leading-tight\">\n <span class=\"tw-text-blue-600 dark:tw-text-blue-400\">{{ getNotificationName(notif) }}</span><span class=\"tw-font-normal tw-text-gray-800 dark:tw-text-gray-300\"> {{ getNotificationAction(notif) }}</span>\n </h4>\n <p class=\"tw-m-0 tw-text-[9px] tw-text-gray-500 dark:tw-text-gray-500 tw-mt-0.5\">{{ getTimeAgo(notif.timestamp) }}</p>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-flex-shrink-0\">\n @if (!isNotificationRead(notif)) {\n <div class=\"tw-w-1.5 tw-h-1.5 tw-rounded-full tw-bg-blue-500 dark:tw-bg-blue-400 tw-animate-pulse\"></div>\n }\n @if (isNotificationAnimating(notif) && isNotificationUndoable(notif)) {\n <button \n type=\"button\"\n (click)=\"undoNotificationRemoval(getNotificationId(notif)); $event.stopPropagation()\"\n class=\"tw-px-2 tw-py-0.5 tw-text-[9px] tw-font-semibold tw-text-blue-600 dark:tw-text-blue-400 tw-bg-blue-50 dark:tw-bg-blue-900 tw-border tw-border-blue-200 dark:tw-border-blue-700 tw-rounded-md tw-cursor-pointer tw-transition-all tw-duration-200 hover:tw-bg-blue-100 dark:hover:tw-bg-blue-800 hover:tw-border-blue-300 dark:hover:tw-border-blue-600 hover:tw-scale-105 tw-whitespace-nowrap tw-animate-pulse\">\n Undo\n </button>\n }\n </div>\n </div>\n \n <!-- Message -->\n @if (notif.message && notif.message !== notif.title) {\n <p class=\"tw-m-0 tw-mt-1 tw-text-[10px] tw-text-gray-700 dark:tw-text-gray-400 tw-leading-snug tw-line-clamp-2\">\n {{ notif.message }}\n </p>\n }\n \n <!-- Comment -->\n @if (notif.data?.comment) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-100 dark:tw-bg-gray-700 tw-rounded-md tw-border-l-2 tw-border-l-blue-500 dark:tw-border-l-blue-500\">\n <p class=\"tw-m-0 tw-text-[10px] tw-text-gray-800 dark:tw-text-gray-300 tw-leading-snug tw-italic tw-line-clamp-2\">{{ notif.data.comment }}</p>\n </div>\n }\n \n <!-- File -->\n @if (notif.data?.file) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-100 dark:tw-bg-gray-700 tw-border tw-border-gray-300 dark:tw-border-gray-600 tw-rounded-md tw-flex tw-items-center tw-gap-2\">\n <div class=\"tw-w-7 tw-h-7 tw-bg-blue-100 dark:tw-bg-blue-900 tw-rounded-md tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\n <span class=\"tw-text-[9px] tw-font-bold tw-text-blue-700 dark:tw-text-blue-300\">{{ getFileIcon(notif.data.file.type) }}</span>\n </div>\n <div class=\"tw-flex-1 tw-min-w-0\">\n <p class=\"tw-m-0 tw-text-[10px] tw-font-semibold tw-text-gray-900 dark:tw-text-gray-100 tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap\">{{ notif.data.file.name }}</p>\n <p class=\"tw-m-0 tw-text-[9px] tw-text-gray-600 dark:tw-text-gray-400\">{{ notif.data.file.size }}</p>\n </div>\n <cide-ele-icon class=\"!tw-text-sm !tw-text-blue-600 dark:!tw-text-blue-400 tw-cursor-pointer tw-transition-all tw-duration-200 tw-flex-shrink-0 hover:tw-text-blue-700 dark:hover:tw-text-blue-300 hover:tw-scale-110\">download</cide-ele-icon>\n </div>\n }\n \n <!-- Action Buttons -->\n @if (notif.action_label) {\n <div class=\"tw-mt-1.5 tw-flex tw-gap-1.5\">\n @if (notif.action_label.toLowerCase().includes('decline')) {\n <button type=\"button\" class=\"tw-py-1 tw-px-3 tw-border tw-border-gray-300 dark:tw-border-gray-600 tw-bg-white dark:tw-bg-gray-800 tw-rounded-md tw-text-[10px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-800 dark:tw-text-gray-300 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-700 hover:tw-border-gray-400 dark:hover:tw-border-gray-500 hover:tw-scale-105\">Decline</button>\n }\n @if (notif.action_label.toLowerCase().includes('accept')) {\n <button type=\"button\" class=\"tw-py-1 tw-px-3 tw-border tw-border-blue-600 dark:tw-border-blue-500 tw-bg-blue-600 dark:tw-bg-blue-500 tw-rounded-md tw-text-[10px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-white hover:tw-bg-blue-700 dark:hover:tw-bg-blue-600 hover:tw-border-blue-700 dark:hover:tw-border-blue-600 hover:tw-scale-105\">Accept</button>\n }\n </div>\n }\n </div>\n </div>\n }\n }\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,rgb(var(--tw-white-rgb) / .95),rgb(var(--tw-gray-50-rgb) / .95));box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:200;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgb(var(--tw-gray-200-rgb) / .8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-sidebar-toggle{display:flex;align-items:center;justify-content:center;border:none;background:transparent;outline:none;transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;flex-shrink:0}.header-sidebar-toggle:hover{background-color:rgb(var(--tw-gray-100-rgb) / .8);transform:scale(1.08)}.header-sidebar-toggle:active{transform:scale(.92);transition:transform .15s cubic-bezier(.4,0,.2,1)}.header-sidebar-toggle:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:.5rem}.header-sidebar-toggle cide-ele-icon{transition:transform .4s cubic-bezier(.4,0,.2,1),opacity .3s cubic-bezier(.4,0,.2,1);display:inline-block;transform-origin:center}.header-sidebar-toggle:hover cide-ele-icon{transform:scale(1.15) rotate(5deg)}.header-sidebar-toggle.animating cide-ele-icon{animation:iconRotate .4s cubic-bezier(.4,0,.2,1)}@keyframes iconRotate{0%{transform:rotate(0) scale(1);opacity:.8}50%{transform:rotate(180deg) scale(1.15);opacity:1}to{transform:rotate(360deg) scale(1);opacity:1}}.header-sidebar-toggle cide-ele-icon{transition:transform .4s cubic-bezier(.4,0,.2,1),opacity .3s cubic-bezier(.4,0,.2,1),color .3s cubic-bezier(.4,0,.2,1);display:inline-block;transform-origin:center}.header-sidebar-toggle.animating cide-ele-icon{animation:iconFadeRotate .4s cubic-bezier(.4,0,.2,1)}@keyframes iconFadeRotate{0%{opacity:1;transform:scale(1) rotate(0)}50%{opacity:.3;transform:scale(.8) rotate(180deg)}to{opacity:1;transform:scale(1) rotate(360deg)}}:root[data-theme=dark] .header-sidebar-toggle,:root.dark-mode .header-sidebar-toggle{color:var(--cide-theme-text-color)}:root[data-theme=dark] .header-sidebar-toggle:hover,:root.dark-mode .header-sidebar-toggle:hover{background-color:var(--cide-theme-hover-bg-color);color:var(--cide-theme-color-brand-primary)}.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,rgb(var(--tw-white-rgb) / 0),rgb(var(--tw-white-rgb) / .3),rgb(var(--tw-white-rgb) / 0));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:rgb(var(--tw-gray-50-rgb) / .8);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:rgb(var(--tw-white-rgb) / 1);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:rgb(var(--tw-gray-700-rgb) / .9);color:rgb(var(--tw-white-rgb) / 1);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:-2px;right:-2px;min-width:18px;height:18px;border-radius:9px;background-color:#ef4444;color:rgb(var(--tw-white-rgb) / 1);font-size:10px;display:flex!important;align-items:center;justify-content:center;padding:0 5px;box-shadow:0 2px 4px #ef444466;font-weight:700;z-index:10;transition:all .2s ease;line-height:1;border:2px solid #ffffff}.header-icon:hover .header-badge{transform:scale(1.15);box-shadow:0 3px 6px #ef444480}.header-icon.notification-icon{position:relative;overflow:visible}.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:rgb(var(--tw-white-rgb) / 1);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}:root[data-theme=dark] .cide-lyt-header,:root.dark-mode .cide-lyt-header{background:linear-gradient(to right,var(--cide-theme-light-color),var(--cide-theme-hover-bg-color));border-bottom-color:var(--cide-theme-border-color);box-shadow:0 2px 8px var(--cide-theme-shadow-color)}:root[data-theme=dark] .header-icon,:root.dark-mode .header-icon{color:var(--cide-theme-text-color)}:root[data-theme=dark] .header-icon.notification-icon,:root.dark-mode .header-icon.notification-icon{color:#d1d5db}:root[data-theme=dark] .header-icon.notification-icon:hover,:root.dark-mode .header-icon.notification-icon:hover{color:#60a5fa}:root[data-theme=dark] .header-divider,:root.dark-mode .header-divider{background-color:var(--cide-theme-border-color)}:root[data-theme=dark] .header-year-pill,:root.dark-mode .header-year-pill{background:linear-gradient(135deg,#60a5fa33,#3b82f640);border-color:#60a5fa80;color:#60a5fa}:root[data-theme=dark] .header-year-pill .header-year-pill-text,:root.dark-mode .header-year-pill .header-year-pill-text{color:#60a5fa}:root[data-theme=dark] .header-year-pill cide-ele-icon,:root.dark-mode .header-year-pill cide-ele-icon{color:#60a5fa!important}:root[data-theme=dark] .header-year-pill:hover,:root.dark-mode .header-year-pill:hover{background:linear-gradient(135deg,#60a5fa4d,#3b82f659);border-color:#60a5fa99;color:#93c5fd}:root[data-theme=dark] .header-year-pill:hover .header-year-pill-text,:root.dark-mode .header-year-pill:hover .header-year-pill-text{color:#93c5fd}:root[data-theme=dark] .header-year-pill:hover cide-ele-icon,:root.dark-mode .header-year-pill:hover cide-ele-icon{color:#93c5fd!important}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search{background-color:var(--cide-theme-hover-bg-color);border-color:var(--cide-theme-border-color)}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search:hover,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search:hover{background-color:var(--cide-theme-light-color);box-shadow:0 3px 12px var(--cide-theme-shadow-color)}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:var(--cide-theme-label-color)!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){.cide-lyt-header{padding:.5rem .75rem;flex-wrap:wrap;min-height:56px;height:auto}.header-logo-container{padding:.25rem 0}.header-logo-container img,.header-logo-container cide-ele-icon{width:24px;height:24px}.header-logo-container+span{font-size:.875rem;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header-search-container{order:3;flex:1 1 100%;max-width:100%;margin:.5rem 0 0;min-width:0}@media (max-width: 480px){.header-search-container{display:none}}.header-icons-container{gap:.5rem;flex-wrap:wrap;justify-content:flex-end}.header-icon{width:28px;height:28px;margin:0 1px}.header-year-pill{padding:.2rem .5rem;font-size:.625rem;min-height:20px;height:20px}.header-year-pill-text{max-width:80px}.profile-avatar{width:24px;height:24px;font-size:.625rem}.header-divider{display:none}.header-dropdown-container{margin:0 1px}.header-badge{min-width:16px;height:16px;font-size:9px;top:-1px;right:-1px}}@media (max-width: 640px){.cide-lyt-header{padding:.5rem}.header-search-container{max-width:100%;margin:.5rem 0 0}.header-icon{width:26px;height:26px}@media (max-width: 480px){.header-year-pill-text{display:none}.header-year-pill{padding:.2rem;width:28px;justify-content:center}.header-icons-container{gap:.25rem}}}@media (min-width: 769px) and (max-width: 1024px){.header-search-container{max-width:400px;margin:0 1.5rem}.header-icons-container{gap:.75rem}}@media (max-width: 768px) and (orientation: landscape){.cide-lyt-header{min-height:48px;padding:.375rem .75rem}.header-search-container{order:0;flex:0 1 auto;max-width:250px;margin:0 1rem}}.notification-scroll-container{scrollbar-width:thin;scrollbar-color:var(--cide-ele-scrollbar-thumb, #d1d5db) var(--cide-ele-scrollbar-track, transparent)}.notification-scroll-container::-webkit-scrollbar{width:6px;height:6px}.notification-scroll-container::-webkit-scrollbar-track{background:var(--cide-ele-scrollbar-track, transparent)}.notification-scroll-container::-webkit-scrollbar-thumb{background-color:var(--cide-ele-scrollbar-thumb, #d1d5db);border-radius:3px}.notification-scroll-container::-webkit-scrollbar-thumb:hover{background-color:var(--cide-ele-scrollbar-thumb-hover, #9ca3af)}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container{background-color:#fff!important;color:#111827!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container *{color:inherit}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-900{color:#111827!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-800{color:#1f2937!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-700{color:#374151!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-600{color:#4b5563!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-500{color:#6b7280!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-blue-600{color:#2563eb!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-white{background-color:#fff!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-gray-50{background-color:#f9fafb!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-gray-100{background-color:#f3f4f6!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-blue-50{background-color:#eff6ff!important}\n"] }]
|
|
3623
|
+
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 <!-- Sidebar Toggle Button - Only visible when sidebar is visible -->\n @if (isSidebarVisible()) {\n <button \n class=\"header-sidebar-toggle tw-flex tw-items-center tw-justify-center tw-w-10 tw-h-10 tw-rounded-lg tw-text-gray-600 hover:tw-text-gray-900 hover:tw-bg-gray-100 tw-transition-all tw-duration-300 tw-cursor-pointer tw-mr-1\"\n (click)=\"toggleSidebar()\"\n (keydown.enter)=\"toggleSidebar()\"\n (keydown.space)=\"toggleSidebar()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"isSidebarCollapsed() ? 'Expand sidebar menu' : 'Collapse sidebar menu'\"\n [attr.title]=\"isSidebarCollapsed() ? 'Expand sidebar menu' : 'Collapse sidebar menu'\">\n <cide-ele-icon size=\"md\" type=\"none\">\n {{ isSidebarCollapsed() ? 'menu' : 'menu_open' }}\n </cide-ele-icon>\n </button>\n }\n \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 #notificationDropdown\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=\"tw-min-w-[380px] tw-bg-white dark:tw-bg-gray-800 tw-rounded-xl tw-shadow-2xl tw-overflow-hidden tw-text-gray-900 dark:tw-text-gray-100\">\n <!-- Header - Fixed/Sticky -->\n <div class=\"tw-sticky tw-top-0 tw-z-10 tw-px-2.5 tw-py-1 tw-bg-white dark:tw-bg-gray-800 tw-flex tw-justify-between tw-items-center tw-border-b tw-border-gray-200 dark:tw-border-gray-700 tw-backdrop-blur-sm\">\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <div class=\"tw-w-5 tw-h-5 tw-bg-blue-500 tw-rounded tw-flex tw-items-center tw-justify-center tw-shadow-sm\">\n <cide-ele-icon class=\"!tw-text-[10px] !tw-text-white\">notifications</cide-ele-icon>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <h3 class=\"tw-m-0 tw-text-[10px] tw-font-bold tw-text-gray-900 dark:tw-text-gray-100 tw-leading-none\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"tw-bg-red-500 tw-text-white tw-px-1 tw-py-0 tw-rounded-full tw-text-[7px] tw-font-bold tw-leading-none tw-animate-pulse\">{{ unreadCount() }}</span>\n }\n </div>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-0.5\">\n <button \n type=\"button\"\n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-600 dark:tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-200 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-600 hover:tw-text-gray-900 dark:hover:tw-text-gray-200\"\n (click)=\"openNotificationSettings(); $event.stopPropagation()\"\n title=\"Notification Settings\">\n <cide-ele-icon class=\"!tw-text-xs\">settings</cide-ele-icon>\n </button>\n @if (unreadCount() > 0) {\n <button \n type=\"button\"\n class=\"tw-bg-blue-500 tw-text-white tw-px-1 tw-py-0.5 tw-rounded tw-text-[8px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-flex tw-items-center tw-gap-0.5 tw-shadow-sm hover:tw-bg-blue-600 hover:tw-scale-105\"\n (click)=\"markAllAsRead(); $event.stopPropagation()\"\n title=\"Mark all as read\">\n <cide-ele-icon class=\"!tw-text-[9px]\">done_all</cide-ele-icon>\n </button>\n }\n <button \n type=\"button\" \n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-600 dark:tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-200 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-600 hover:tw-text-gray-900 dark:hover:tw-text-gray-200 hover:tw-rotate-90\"\n (click)=\"closeNotificationDropdown($event)\"\n title=\"Close\">\n <cide-ele-icon class=\"!tw-text-xs\">close</cide-ele-icon>\n </button>\n </div>\n </div>\n\n <!-- Notifications List -->\n <div class=\"tw-overflow-x-hidden notification-scroll-container tw-bg-white dark:tw-bg-gray-800 tw-text-gray-900 dark:tw-text-gray-100\">\n @if (notifications().length === 0) {\n <div class=\"tw-py-16 tw-px-4 tw-text-center tw-bg-white dark:tw-bg-gray-800\">\n <cide-ele-icon class=\"!tw-text-6xl !tw-text-gray-300 dark:!tw-text-gray-600 tw-mb-3\">notifications_off</cide-ele-icon>\n <p class=\"tw-m-0 tw-text-sm tw-text-gray-600 dark:tw-text-gray-400 tw-font-medium\">No notifications yet</p>\n <p class=\"tw-m-0 tw-mt-1 tw-text-xs tw-text-gray-500 dark:tw-text-gray-500\">You're all caught up!</p>\n </div>\n } @else {\n @for (notif of notifications().slice(0, 15); track notif.id) {\n <div \n class=\"tw-flex tw-items-start tw-px-3 tw-py-2 tw-cursor-pointer tw-transition-all tw-duration-300 tw-relative tw-gap-2 tw-border-b tw-border-gray-200 dark:tw-border-gray-700 last:tw-border-b-0 hover:tw-bg-gray-50 dark:hover:tw-bg-gray-700 tw-transform tw-ease-in-out tw-bg-white dark:tw-bg-gray-800 tw-text-gray-900 dark:tw-text-gray-100\"\n [class.tw-border-l-2]=\"!isNotificationRead(notif)\"\n [class.tw-border-l-blue-500]=\"!isNotificationRead(notif)\"\n [class.dark:tw-border-l-blue-400]=\"!isNotificationRead(notif)\"\n [class.tw-bg-blue-50]=\"!isNotificationRead(notif)\"\n [class.dark:tw-bg-gray-700]=\"!isNotificationRead(notif)\"\n [class.-tw-translate-x-full]=\"isNotificationAnimating(notif)\"\n [class.tw-opacity-0]=\"isNotificationAnimating(notif)\"\n [class.tw-max-h-0]=\"isNotificationAnimating(notif)\"\n [class.tw-overflow-hidden]=\"isNotificationAnimating(notif)\"\n [class.tw-mb-0]=\"isNotificationAnimating(notif)\"\n [class.tw-p-0]=\"isNotificationAnimating(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <!-- Icon/Avatar -->\n <div class=\"tw-flex-shrink-0 tw-relative\">\n <div class=\"tw-w-9 tw-h-9 tw-rounded-full tw-overflow-hidden tw-bg-gradient-to-br tw-from-blue-500 tw-to-blue-600 tw-flex tw-items-center tw-justify-center tw-shadow-sm tw-ring-1 tw-ring-white\">\n @if (getNotificationAvatar(notif)) {\n <img \n cideEleFileImage \n [fileId]=\"getNotificationAvatar(notif) || ''\"\n [altText]=\"getNotificationName(notif)\"\n class=\"tw-w-full tw-h-full tw-object-cover\">\n } @else {\n <cide-ele-icon class=\"!tw-text-base !tw-text-white\">{{ getNotificationIcon(notif.type) }}</cide-ele-icon>\n }\n </div>\n <!-- Green online indicator -->\n <div class=\"tw-absolute tw-bottom-0 tw-right-0 tw-w-2 tw-h-2 tw-bg-green-500 tw-rounded-full tw-border tw-border-white\"></div>\n </div>\n\n <!-- Content -->\n <div class=\"tw-flex-1 tw-min-w-0\">\n <!-- Title and relative time -->\n <div class=\"tw-flex tw-items-start tw-justify-between tw-gap-1.5 tw-mb-0.5\">\n <div class=\"tw-flex-1 tw-min-w-0\">\n <h4 class=\"tw-m-0 tw-text-[11px] tw-font-bold tw-text-gray-900 dark:tw-text-gray-100 tw-leading-tight\">\n <span class=\"tw-text-blue-600 dark:tw-text-blue-400\">{{ getNotificationName(notif) }}</span><span class=\"tw-font-normal tw-text-gray-800 dark:tw-text-gray-300\"> {{ getNotificationAction(notif) }}</span>\n </h4>\n <p class=\"tw-m-0 tw-text-[9px] tw-text-gray-500 dark:tw-text-gray-500 tw-mt-0.5\">{{ getTimeAgo(notif.timestamp) }}</p>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-flex-shrink-0\">\n @if (!isNotificationRead(notif)) {\n <div class=\"tw-w-1.5 tw-h-1.5 tw-rounded-full tw-bg-blue-500 dark:tw-bg-blue-400 tw-animate-pulse\"></div>\n }\n @if (isNotificationAnimating(notif) && isNotificationUndoable(notif)) {\n <button \n type=\"button\"\n (click)=\"undoNotificationRemoval(getNotificationId(notif)); $event.stopPropagation()\"\n class=\"tw-px-2 tw-py-0.5 tw-text-[9px] tw-font-semibold tw-text-blue-600 dark:tw-text-blue-400 tw-bg-blue-50 dark:tw-bg-blue-900 tw-border tw-border-blue-200 dark:tw-border-blue-700 tw-rounded-md tw-cursor-pointer tw-transition-all tw-duration-200 hover:tw-bg-blue-100 dark:hover:tw-bg-blue-800 hover:tw-border-blue-300 dark:hover:tw-border-blue-600 hover:tw-scale-105 tw-whitespace-nowrap tw-animate-pulse\">\n Undo\n </button>\n }\n </div>\n </div>\n \n <!-- Message -->\n @if (notif.message && notif.message !== notif.title) {\n <p class=\"tw-m-0 tw-mt-1 tw-text-[10px] tw-text-gray-700 dark:tw-text-gray-400 tw-leading-snug tw-line-clamp-2\">\n {{ notif.message }}\n </p>\n }\n \n <!-- Comment -->\n @if (notif.data?.comment) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-100 dark:tw-bg-gray-700 tw-rounded-md tw-border-l-2 tw-border-l-blue-500 dark:tw-border-l-blue-500\">\n <p class=\"tw-m-0 tw-text-[10px] tw-text-gray-800 dark:tw-text-gray-300 tw-leading-snug tw-italic tw-line-clamp-2\">{{ notif.data.comment }}</p>\n </div>\n }\n \n <!-- File -->\n @if (notif.data?.file) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-100 dark:tw-bg-gray-700 tw-border tw-border-gray-300 dark:tw-border-gray-600 tw-rounded-md tw-flex tw-items-center tw-gap-2\">\n <div class=\"tw-w-7 tw-h-7 tw-bg-blue-100 dark:tw-bg-blue-900 tw-rounded-md tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\n <span class=\"tw-text-[9px] tw-font-bold tw-text-blue-700 dark:tw-text-blue-300\">{{ getFileIcon(notif.data.file.type) }}</span>\n </div>\n <div class=\"tw-flex-1 tw-min-w-0\">\n <p class=\"tw-m-0 tw-text-[10px] tw-font-semibold tw-text-gray-900 dark:tw-text-gray-100 tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap\">{{ notif.data.file.name }}</p>\n <p class=\"tw-m-0 tw-text-[9px] tw-text-gray-600 dark:tw-text-gray-400\">{{ notif.data.file.size }}</p>\n </div>\n <cide-ele-icon class=\"!tw-text-sm !tw-text-blue-600 dark:!tw-text-blue-400 tw-cursor-pointer tw-transition-all tw-duration-200 tw-flex-shrink-0 hover:tw-text-blue-700 dark:hover:tw-text-blue-300 hover:tw-scale-110\">download</cide-ele-icon>\n </div>\n }\n \n <!-- Action Buttons -->\n @if (notif.action_label) {\n <div class=\"tw-mt-1.5 tw-flex tw-gap-1.5\">\n @if (notif.action_label.toLowerCase().includes('decline')) {\n <button type=\"button\" class=\"tw-py-1 tw-px-3 tw-border tw-border-gray-300 dark:tw-border-gray-600 tw-bg-white dark:tw-bg-gray-800 tw-rounded-md tw-text-[10px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-800 dark:tw-text-gray-300 hover:tw-bg-gray-100 dark:hover:tw-bg-gray-700 hover:tw-border-gray-400 dark:hover:tw-border-gray-500 hover:tw-scale-105\">Decline</button>\n }\n @if (notif.action_label.toLowerCase().includes('accept')) {\n <button type=\"button\" class=\"tw-py-1 tw-px-3 tw-border tw-border-blue-600 dark:tw-border-blue-500 tw-bg-blue-600 dark:tw-bg-blue-500 tw-rounded-md tw-text-[10px] tw-font-semibold tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-white hover:tw-bg-blue-700 dark:hover:tw-bg-blue-600 hover:tw-border-blue-700 dark:hover:tw-border-blue-600 hover:tw-scale-105\">Accept</button>\n }\n </div>\n }\n </div>\n </div>\n }\n }\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,rgb(var(--tw-white-rgb) / .95),rgb(var(--tw-gray-50-rgb) / .95));box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:200;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgb(var(--tw-gray-200-rgb) / .8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-sidebar-toggle{display:flex;align-items:center;justify-content:center;border:none;background:transparent;outline:none;transition:background-color .2s ease;position:relative;flex-shrink:0}.header-sidebar-toggle:hover{background-color:rgb(var(--tw-gray-100-rgb) / .8)}.header-sidebar-toggle:active{background-color:rgb(var(--tw-gray-200-rgb) / .8)}.header-sidebar-toggle:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:.5rem}.header-sidebar-toggle cide-ele-icon{transition:transform .2s ease,opacity .2s ease;display:inline-block;transform-origin:center}.header-sidebar-toggle:hover cide-ele-icon{transform:scale(1.1)}:root[data-theme=dark] .header-sidebar-toggle,:root.dark-mode .header-sidebar-toggle{color:var(--cide-theme-text-color)}:root[data-theme=dark] .header-sidebar-toggle:hover,:root.dark-mode .header-sidebar-toggle:hover{background-color:var(--cide-theme-hover-bg-color);color:var(--cide-theme-color-brand-primary)}.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,rgb(var(--tw-white-rgb) / 0),rgb(var(--tw-white-rgb) / .3),rgb(var(--tw-white-rgb) / 0));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:rgb(var(--tw-gray-50-rgb) / .8);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:rgb(var(--tw-white-rgb) / 1);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:rgb(var(--tw-gray-700-rgb) / .9);color:rgb(var(--tw-white-rgb) / 1);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:-2px;right:-2px;min-width:18px;height:18px;border-radius:9px;background-color:#ef4444;color:rgb(var(--tw-white-rgb) / 1);font-size:10px;display:flex!important;align-items:center;justify-content:center;padding:0 5px;box-shadow:0 2px 4px #ef444466;font-weight:700;z-index:10;transition:all .2s ease;line-height:1;border:2px solid #ffffff}.header-icon:hover .header-badge{transform:scale(1.15);box-shadow:0 3px 6px #ef444480}.header-icon.notification-icon{position:relative;overflow:visible}.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:rgb(var(--tw-white-rgb) / 1);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}:root[data-theme=dark] .cide-lyt-header,:root.dark-mode .cide-lyt-header{background:linear-gradient(to right,var(--cide-theme-light-color),var(--cide-theme-hover-bg-color));border-bottom-color:var(--cide-theme-border-color);box-shadow:0 2px 8px var(--cide-theme-shadow-color)}:root[data-theme=dark] .header-icon,:root.dark-mode .header-icon{color:var(--cide-theme-text-color)}:root[data-theme=dark] .header-icon.notification-icon,:root.dark-mode .header-icon.notification-icon{color:#d1d5db}:root[data-theme=dark] .header-icon.notification-icon:hover,:root.dark-mode .header-icon.notification-icon:hover{color:#60a5fa}:root[data-theme=dark] .header-divider,:root.dark-mode .header-divider{background-color:var(--cide-theme-border-color)}:root[data-theme=dark] .header-year-pill,:root.dark-mode .header-year-pill{background:linear-gradient(135deg,#60a5fa33,#3b82f640);border-color:#60a5fa80;color:#60a5fa}:root[data-theme=dark] .header-year-pill .header-year-pill-text,:root.dark-mode .header-year-pill .header-year-pill-text{color:#60a5fa}:root[data-theme=dark] .header-year-pill cide-ele-icon,:root.dark-mode .header-year-pill cide-ele-icon{color:#60a5fa!important}:root[data-theme=dark] .header-year-pill:hover,:root.dark-mode .header-year-pill:hover{background:linear-gradient(135deg,#60a5fa4d,#3b82f659);border-color:#60a5fa99;color:#93c5fd}:root[data-theme=dark] .header-year-pill:hover .header-year-pill-text,:root.dark-mode .header-year-pill:hover .header-year-pill-text{color:#93c5fd}:root[data-theme=dark] .header-year-pill:hover cide-ele-icon,:root.dark-mode .header-year-pill:hover cide-ele-icon{color:#93c5fd!important}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search{background-color:var(--cide-theme-hover-bg-color);border-color:var(--cide-theme-border-color)}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search:hover,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search:hover{background-color:var(--cide-theme-light-color);box-shadow:0 3px 12px var(--cide-theme-shadow-color)}:root[data-theme=dark] ::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon,:root.dark-mode ::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:var(--cide-theme-label-color)!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){.cide-lyt-header{padding:.5rem .75rem;flex-wrap:wrap;min-height:56px;height:auto}.header-logo-container{padding:.25rem 0}.header-logo-container img,.header-logo-container cide-ele-icon{width:24px;height:24px}.header-logo-container+span{font-size:.875rem;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header-search-container{order:3;flex:1 1 100%;max-width:100%;margin:.5rem 0 0;min-width:0}@media (max-width: 480px){.header-search-container{display:none}}.header-icons-container{gap:.5rem;flex-wrap:wrap;justify-content:flex-end}.header-icon{width:28px;height:28px;margin:0 1px}.header-year-pill{padding:.2rem .5rem;font-size:.625rem;min-height:20px;height:20px}.header-year-pill-text{max-width:80px}.profile-avatar{width:24px;height:24px;font-size:.625rem}.header-divider{display:none}.header-dropdown-container{margin:0 1px}.header-badge{min-width:16px;height:16px;font-size:9px;top:-1px;right:-1px}}@media (max-width: 640px){.cide-lyt-header{padding:.5rem}.header-search-container{max-width:100%;margin:.5rem 0 0}.header-icon{width:26px;height:26px}@media (max-width: 480px){.header-year-pill-text{display:none}.header-year-pill{padding:.2rem;width:28px;justify-content:center}.header-icons-container{gap:.25rem}}}@media (min-width: 769px) and (max-width: 1024px){.header-search-container{max-width:400px;margin:0 1.5rem}.header-icons-container{gap:.75rem}}@media (max-width: 768px) and (orientation: landscape){.cide-lyt-header{min-height:48px;padding:.375rem .75rem}.header-search-container{order:0;flex:0 1 auto;max-width:250px;margin:0 1rem}}.notification-scroll-container{scrollbar-width:thin;scrollbar-color:var(--cide-ele-scrollbar-thumb, #d1d5db) var(--cide-ele-scrollbar-track, transparent)}.notification-scroll-container::-webkit-scrollbar{width:6px;height:6px}.notification-scroll-container::-webkit-scrollbar-track{background:var(--cide-ele-scrollbar-track, transparent)}.notification-scroll-container::-webkit-scrollbar-thumb{background-color:var(--cide-ele-scrollbar-thumb, #d1d5db);border-radius:3px}.notification-scroll-container::-webkit-scrollbar-thumb:hover{background-color:var(--cide-ele-scrollbar-thumb-hover, #9ca3af)}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container{background-color:#fff!important;color:#111827!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container *{color:inherit}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-900{color:#111827!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-800{color:#1f2937!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-700{color:#374151!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-600{color:#4b5563!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-gray-500{color:#6b7280!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-text-blue-600{color:#2563eb!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-white{background-color:#fff!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-gray-50{background-color:#f9fafb!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-gray-100{background-color:#f3f4f6!important}:root:not([data-theme=dark]):not(.dark-mode) .notification-scroll-container .tw-bg-blue-50{background-color:#eff6ff!important}\n"] }]
|
|
3600
3624
|
}], ctorParameters: () => [], propDecorators: { triggerTemplate: [{
|
|
3601
3625
|
type: ViewChild,
|
|
3602
3626
|
args: ['triggerTemplate']
|
|
@@ -5168,8 +5192,8 @@ class CideLytSidedrawerWrapperComponent {
|
|
|
5168
5192
|
}
|
|
5169
5193
|
ngOnInit() {
|
|
5170
5194
|
// Initialize the component map (You'd likely populate this from a config or service)
|
|
5171
|
-
this.componentMap['drowar_notes'] = () => import('./cloud-ide-layout-sidedrawer-notes.component-
|
|
5172
|
-
this.componentMap['drawer_theme'] = () => import('./cloud-ide-layout-drawer-theme.component-
|
|
5195
|
+
this.componentMap['drowar_notes'] = () => import('./cloud-ide-layout-sidedrawer-notes.component-DOxcfBdm.mjs').then(m => m.CideLytSidedrawerNotesComponent);
|
|
5196
|
+
this.componentMap['drawer_theme'] = () => import('./cloud-ide-layout-drawer-theme.component-DoXf1jLH.mjs').then(m => m.CideLytDrawerThemeComponent);
|
|
5173
5197
|
}
|
|
5174
5198
|
async loadComponent(configFor) {
|
|
5175
5199
|
console.log('🔍 SIDEDRAWER - Loading component:', configFor, 'Current tab:', this.currentTabId);
|
|
@@ -6861,7 +6885,7 @@ const layoutControlPannelChildRoutes = [{
|
|
|
6861
6885
|
},
|
|
6862
6886
|
{
|
|
6863
6887
|
path: "home",
|
|
6864
|
-
loadComponent: () => import('./cloud-ide-layout-home-wrapper.component-
|
|
6888
|
+
loadComponent: () => import('./cloud-ide-layout-home-wrapper.component-DjVrTMDM.mjs').then(c => c.CideLytHomeWrapperComponent),
|
|
6865
6889
|
canActivate: [authGuard],
|
|
6866
6890
|
data: {
|
|
6867
6891
|
sypg_page_code: "cide_lyt_home" // Used by RequestService to fetch tab properties
|
|
@@ -6869,7 +6893,7 @@ const layoutControlPannelChildRoutes = [{
|
|
|
6869
6893
|
},
|
|
6870
6894
|
{
|
|
6871
6895
|
path: "dashboard-manager",
|
|
6872
|
-
loadComponent: () => import('./cloud-ide-layout-dashboard-manager.component-
|
|
6896
|
+
loadComponent: () => import('./cloud-ide-layout-dashboard-manager.component-DStneI1a.mjs').then(c => c.DashboardManagerComponent),
|
|
6873
6897
|
canActivate: [authGuard],
|
|
6874
6898
|
data: {
|
|
6875
6899
|
sypg_page_code: "cide_lyt_dashboard_manager"
|
|
@@ -8436,4 +8460,4 @@ var floatingEntityRightsSharing_component = /*#__PURE__*/Object.freeze({
|
|
|
8436
8460
|
*/
|
|
8437
8461
|
|
|
8438
8462
|
export { AppStateHelperService as A, CideLytSharedWrapperComponent as C, ENVIRONMENT_CONFIG as E, NotificationSettingsService as N, RightsService as R, CideLytSidebarService as a, CideLytSidedrawerService as b, CideLytThemeService as c, AppStateService as d, CloudIdeLayoutService as e, CloudIdeLayoutComponent as f, CideLytSharedService as g, ComponentContextService 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 };
|
|
8439
|
-
//# sourceMappingURL=cloud-ide-layout-cloud-ide-layout-
|
|
8463
|
+
//# sourceMappingURL=cloud-ide-layout-cloud-ide-layout-B84fwD52.mjs.map
|