cloud-ide-layout 1.0.68 → 1.0.70
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-w1krh2y4.mjs → cloud-ide-layout-cloud-ide-layout-B3UJ3l6Z.mjs} +7 -7
- package/fesm2022/cloud-ide-layout-cloud-ide-layout-B3UJ3l6Z.mjs.map +1 -0
- package/fesm2022/{cloud-ide-layout-drawer-theme.component-AftnS8IB.mjs → cloud-ide-layout-drawer-theme.component-DMMPXwHK.mjs} +2 -2
- package/fesm2022/{cloud-ide-layout-drawer-theme.component-AftnS8IB.mjs.map → cloud-ide-layout-drawer-theme.component-DMMPXwHK.mjs.map} +1 -1
- package/fesm2022/{cloud-ide-layout-floating-entity-selection.component-JgWMB6Cx.mjs → cloud-ide-layout-floating-entity-selection.component--Gd3n0L1.mjs} +2 -2
- package/fesm2022/{cloud-ide-layout-floating-entity-selection.component-JgWMB6Cx.mjs.map → cloud-ide-layout-floating-entity-selection.component--Gd3n0L1.mjs.map} +1 -1
- package/fesm2022/{cloud-ide-layout-home-wrapper.component-CGywS2UB.mjs → cloud-ide-layout-home-wrapper.component-CqXQq2xa.mjs} +2 -2
- package/fesm2022/{cloud-ide-layout-home-wrapper.component-CGywS2UB.mjs.map → cloud-ide-layout-home-wrapper.component-CqXQq2xa.mjs.map} +1 -1
- package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-BelpcVYV.mjs → cloud-ide-layout-sidedrawer-notes.component-CsFwJdTC.mjs} +2 -2
- package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-BelpcVYV.mjs.map → cloud-ide-layout-sidedrawer-notes.component-CsFwJdTC.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-w1krh2y4.mjs.map +0 -1
|
@@ -1266,7 +1266,7 @@ class CideLytFloatingEntitySelectionService {
|
|
|
1266
1266
|
}
|
|
1267
1267
|
try {
|
|
1268
1268
|
// Use relative import to avoid circular dependency
|
|
1269
|
-
const module = await import('./cloud-ide-layout-floating-entity-selection.component
|
|
1269
|
+
const module = await import('./cloud-ide-layout-floating-entity-selection.component--Gd3n0L1.mjs');
|
|
1270
1270
|
if (module.CideLytFloatingEntitySelectionComponent) {
|
|
1271
1271
|
this.containerService.registerComponent('entity-selection-header', module.CideLytFloatingEntitySelectionComponent);
|
|
1272
1272
|
console.log('✅ Entity selection component registered successfully');
|
|
@@ -2388,12 +2388,12 @@ class CideLytHeaderWrapperComponent {
|
|
|
2388
2388
|
}
|
|
2389
2389
|
}
|
|
2390
2390
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytHeaderWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2391
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideLytHeaderWrapperComponent, isStandalone: true, selector: "cide-lyt-header-wrapper", viewQueries: [{ propertyName: "triggerTemplate", first: true, predicate: ["triggerTemplate"], descendants: true }, { propertyName: "financialYearTriggerTemplate", first: true, predicate: ["financialYearTriggerTemplate"], descendants: true }, { propertyName: "academicYearTriggerTemplate", first: true, predicate: ["academicYearTriggerTemplate"], descendants: true }, { propertyName: "notificationTriggerTemplate", first: true, predicate: ["notificationTriggerTemplate"], descendants: true }, { 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 <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-w-full tw-max-w-[360px] tw-min-w-[340px] tw-bg-white tw-rounded-lg tw-shadow-lg tw-overflow-hidden tw-flex tw-flex-col tw-max-h-[85vh]\">\n <!-- Header -->\n <div class=\"tw-px-4 tw-py-2.5 tw-bg-white tw-border-b tw-border-b-gray-100 tw-flex tw-justify-between tw-items-center tw-sticky tw-top-0 tw-z-10\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <h3 class=\"tw-m-0 tw-text-sm tw-font-semibold tw-text-gray-900\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"tw-bg-gray-500 tw-text-white tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-[10px] tw-font-medium tw-min-w-4 tw-text-center tw-leading-none\">{{ unreadCount() }}</span>\n }\n </div>\n <button \n type=\"button\" \n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-150 tw-w-6 tw-h-6 hover:tw-bg-gray-100 hover:tw-text-gray-600\"\n (click)=\"closeNotificationDropdown($event)\">\n <cide-ele-icon class=\"!tw-text-base\">close</cide-ele-icon>\n </button>\n </div>\n\n <!-- Notifications List -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-p-0 [&::-webkit-scrollbar]:tw-w-1 [&::-webkit-scrollbar-track]:tw-bg-transparent [&::-webkit-scrollbar-thumb]:tw-bg-gray-300 [&::-webkit-scrollbar-thumb]:tw-rounded-full [&::-webkit-scrollbar-thumb]:hover:tw-bg-gray-400\">\n @if (notifications().length === 0) {\n <div class=\"tw-py-10 tw-px-4 tw-text-center\">\n <cide-ele-icon class=\"!tw-text-4xl !tw-text-gray-300 tw-mb-2\">notifications_off</cide-ele-icon>\n <p class=\"tw-m-0 tw-text-xs tw-text-gray-400 tw-font-medium\">No notifications</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.5 tw-cursor-pointer tw-transition-colors tw-duration-150 tw-relative tw-gap-2 tw-border-b tw-border-b-gray-50 hover:tw-bg-gray-50/50\"\n [class.tw-bg-white]=\"!isNotificationRead(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <!-- Profile Avatar -->\n <div class=\"tw-flex-shrink-0 tw-w-8 tw-h-8 tw-rounded-full tw-overflow-hidden tw-bg-gray-200 tw-flex tw-items-center tw-justify-center tw-relative\">\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 <div class=\"tw-w-full tw-h-full tw-bg-gradient-to-br tw-from-indigo-500 tw-to-purple-600 tw-text-white tw-flex tw-items-center tw-justify-center\">\n <cide-ele-icon class=\"!tw-text-sm !tw-text-white\">{{ getNotificationIcon(notif.type) }}</cide-ele-icon>\n </div>\n }\n </div>\n\n <!-- Content -->\n <div class=\"tw-flex-1 tw-min-w-0 tw-flex tw-flex-col tw-gap-0 tw-pr-3\">\n <div class=\"tw-flex tw-items-start tw-justify-between tw-gap-2\">\n <div class=\"tw-flex-1 tw-min-w-0\">\n <div class=\"tw-text-xs tw-text-gray-900 tw-leading-tight\">\n <span class=\"tw-font-semibold tw-text-gray-900\">{{ getNotificationName(notif) }}</span>\n <span class=\"tw-font-normal tw-text-gray-600\">{{ getNotificationAction(notif) }}</span>\n </div>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1.5 tw-flex-shrink-0\">\n <div class=\"tw-text-[10px] tw-text-gray-400 tw-whitespace-nowrap\">{{ getTimeAgo(notif.timestamp) }}</div>\n @if (!isNotificationRead(notif)) {\n <div class=\"tw-w-1.5 tw-h-1.5 tw-rounded-full tw-bg-blue-500 tw-flex-shrink-0\"></div>\n }\n </div>\n </div>\n <div class=\"tw-text-[10px] tw-text-gray-500 tw-mt-0.5\">{{ getFullTime(notif.timestamp) }}</div>\n @if (notif.message && notif.message !== notif.title) {\n <div class=\"tw-mt-1 tw-text-xs tw-text-gray-600 tw-leading-relaxed\">\n {{ notif.message }}\n </div>\n }\n @if (notif.data?.comment) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-50 tw-rounded tw-border-l-2 tw-border-l-blue-500 tw-text-[11px] tw-text-gray-700 tw-leading-relaxed\">\n {{ notif.data.comment }}\n </div>\n }\n @if (notif.data?.file) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2 tw-bg-gray-50 tw-border tw-border-gray-200 tw-rounded tw-flex tw-items-center tw-gap-1.5\">\n <div class=\"tw-w-7 tw-h-7 tw-bg-gray-300 tw-rounded tw-flex tw-items-center tw-justify-center tw-text-[9px] tw-font-semibold tw-text-white tw-flex-shrink-0\">{{ getFileIcon(notif.data.file.type) }}</div>\n <div class=\"tw-flex-1 tw-min-w-0\">\n <div class=\"tw-text-[11px] tw-font-medium tw-text-gray-900 tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap\">{{ notif.data.file.name }}</div>\n <div class=\"tw-text-[9px] tw-text-gray-500\">{{ notif.data.file.size }}</div>\n </div>\n <cide-ele-icon class=\"tw-text-gray-400 tw-cursor-pointer tw-transition-colors tw-duration-150 tw-flex-shrink-0 tw-text-xs hover:tw-text-blue-500\">download</cide-ele-icon>\n </div>\n }\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-0.5 tw-px-2.5 tw-border tw-border-gray-200 tw-bg-white tw-rounded tw-text-[11px] tw-font-medium tw-cursor-pointer tw-transition-all tw-duration-150 tw-text-gray-600 hover:tw-bg-gray-50 hover:tw-border-gray-300\">Decline</button>\n }\n @if (notif.action_label.toLowerCase().includes('accept')) {\n <button type=\"button\" class=\"tw-py-0.5 tw-px-2.5 tw-border tw-border-blue-500 tw-bg-blue-500 tw-rounded tw-text-[11px] tw-font-medium tw-cursor-pointer tw-transition-all tw-duration-150 tw-text-white hover:tw-bg-blue-600 hover:tw-border-blue-600\">Accept</button>\n }\n </div>\n }\n </div>\n </div>\n }\n }\n </div>\n </div>\n </ng-template>\n\n <div class=\"header-divider\"></div>\n\n <!-- Profile with Dropdown -->\n <div class=\"header-icon user-profile\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"profileItems\" [config]=\"profileConfig\"\n [triggerTemplate]=\"triggerTemplate\"\n (itemClick)=\"onProfileClick($event)\">\n <ng-template #triggerTemplate>\n @if (appStateService.currentUser()?.user_photo_id_cyfm) {\n <div class=\"profile-avatar\">\n <img cideEleFileImage [fileId]=\"(appStateService.currentUser()?.user_photo_id_cyfm || '')\"\n [altText]=\"'User Profile Photo'\" class=\"tw-w-full tw-h-full tw-object-cover tw-rounded-full\">\n </div>\n } @else {\n <div class=\"profile-avatar\">\n <cide-ele-icon name=\"person\" class=\"tw-w-6 tw-h-6 tw-text-white\"></cide-ele-icon>\n </div>\n }\n </ng-template>\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">My Account</div>\n </div>\n </div>\n</header>", styles: [".cide-lyt-header{display:flex;align-items:center;justify-content:space-between;background:linear-gradient(to right,#fffffff2,#f9fafbf2);box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:20;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgba(229,231,235,.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-logo-container{height:100%;display:flex;align-items:center;padding:.5rem 0;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);border-radius:8px;outline:none}.header-logo-container img{height:30px;max-height:100%;transition:all .3s ease;border-radius:5px;overflow:hidden;box-shadow:0 1px 4px #0000000d}.header-logo-container:hover img{transform:scale(1.03);filter:brightness(1.05);box-shadow:0 2px 6px #00000014}.header-logo-container:after{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:linear-gradient(to bottom right,#fff0,#ffffff4d,#fff0);transform:rotate(30deg);opacity:0;transition:transform .6s ease,opacity .6s ease;pointer-events:none}.header-logo-container:hover:after,.header-logo-container:focus:after{opacity:1;transform:rotate(30deg) translate(50%,50%)}.header-search-container{flex-grow:1;max-width:600px;margin:0 2rem;position:relative;transition:all .3s ease}::ng-deep .header-search-container #cide_lyt_header_search{width:100%;background-color:#f9fafbcc;border-radius:20px!important;transition:all .3s ease;overflow:visible;transform:translateZ(0)}::ng-deep .header-search-container #cide_lyt_header_search:hover{box-shadow:0 3px 12px #00000014;background-color:#fff;transform:translateY(-1px)}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-input{background-color:transparent;font-size:.85rem!important;letter-spacing:.01em}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:#6b7280b3!important;font-size:1.1rem!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within{transform:translateY(-1px) scale(1.01)}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-input{border-color:#3b82f6!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-leading-icon{color:#3b82f6!important}.header-icons-container{display:flex;align-items:center;gap:1rem}.header-icon{position:relative;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-dropdown-container{position:relative;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-icon:before{content:\"\";position:absolute;inset:0;background-color:#3b82f61a;border-radius:.5rem;opacity:0;transform:scale(.8);transition:all .2s cubic-bezier(.4,0,.2,1)}.header-icon:hover:before{opacity:1;transform:scale(1)}.header-icon:hover{color:#3b82f6}.header-icon:active{transform:scale(.95)}.header-tooltip{position:absolute;bottom:-26px;left:50%;transform:translate(-50%);background-color:#374151e6;color:#fff;padding:.25rem .6rem;border-radius:.25rem;font-size:.7rem;white-space:nowrap;opacity:0;pointer-events:none;transition:all .2s cubic-bezier(.4,0,.2,1);z-index:1000;box-shadow:0 2px 5px #0003;letter-spacing:.01em;will-change:transform,opacity}.header-tooltip:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:5px;border-style:solid;border-color:transparent transparent rgba(55,65,81,.9) transparent}.header-icon:hover .header-tooltip{opacity:1;transform:translate(-50%) translateY(0)}.header-badge{position:absolute;top:0;right:0;min-width:16px;height:16px;border-radius:8px;background-color:#ef4444;color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 1px 3px #ef44444d;font-weight:600;z-index:2;transition:all .2s ease}.header-icon:hover .header-badge{transform:scale(1.1)}.header-divider{height:20px;width:1px;background-color:#e5e7ebcc;margin:0 6px}.header-year-dropdown-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.header-year-pill{position:relative;display:flex;align-items:center;padding:.25rem .625rem;background:linear-gradient(135deg,#3b82f61a,#2563eb26);border:1px solid rgba(59,130,246,.3);border-radius:9999px;color:#2563eb;font-size:.6875rem;font-weight:600;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;white-space:nowrap;box-shadow:0 1px 2px #3b82f61a;min-height:22px;height:22px;line-height:1}.header-year-pill:hover{background:linear-gradient(135deg,#3b82f626,#2563eb33);border-color:#3b82f666;transform:translateY(-1px);box-shadow:0 2px 6px #3b82f626}.header-year-pill-text{max-width:180px;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em;line-height:1;display:inline-block}::ng-deep .header-dropdown-container .dropdown-trigger{background:transparent!important;border:none!important;border-radius:0!important;padding:0!important;width:100%!important;height:100%!important;min-width:auto!important;box-shadow:none!important;display:flex!important;align-items:center!important;justify-content:center!important;transition:none!important;cursor:pointer!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover{background:transparent!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover .header-year-pill{background:linear-gradient(135deg,#3b82f626,#2563eb33)!important;border-color:#3b82f666!important;transform:translateY(-1px)!important;box-shadow:0 2px 6px #3b82f626!important}::ng-deep .header-dropdown-container .dropdown-trigger:focus,::ng-deep .header-dropdown-container .dropdown-trigger:focus-visible,::ng-deep .header-dropdown-container .dropdown-trigger:active{outline:none!important;box-shadow:0 2px 6px #3b82f626!important}.profile-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;font-size:.75rem;font-weight:600;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #2563eb33;transition:all .2s cubic-bezier(.4,0,.2,1);letter-spacing:-.5px;cursor:pointer;border:2px solid transparent}.profile-avatar:hover,.header-icon:hover .profile-avatar{transform:scale(1.08);box-shadow:0 3px 8px #2563eb4d;border-color:#3b82f64d}::ng-deep .user-profile .dropdown-trigger{background:transparent!important;border:none!important;padding:0!important;width:auto!important;height:auto!important;border-radius:0!important}::ng-deep .user-profile .dropdown-trigger:hover{background:transparent!important}::ng-deep .user-profile .dropdown-trigger:focus,::ng-deep .user-profile .dropdown-trigger:focus-visible,::ng-deep .user-profile .dropdown-trigger:active{outline:none!important;box-shadow:none!important}.header-avatar{width:36px;height:36px;border-radius:50%;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);border:2px solid transparent;box-shadow:0 2px 4px #0000001a}.header-avatar:hover{border-color:#3b82f6;transform:scale(1.05);box-shadow:0 3px 6px #3b82f64d}@media (max-width: 768px){.header-search-container{margin:0 1rem}.header-icons-container{gap:.5rem}}@media (max-width: 640px){.header-search-container{max-width:200px;margin:0 .5rem}}\n"], dependencies: [{ kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "size"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleDropdownComponent, selector: "cide-ele-dropdown", inputs: ["items", "config", "triggerTemplate", "menuTemplate"], outputs: ["itemClick", "dropdownToggle"] }, { kind: "directive", type: CideEleFileImageDirective, selector: "[cideEleFileImage]", inputs: ["fileId", "altText"] }] });
|
|
2391
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideLytHeaderWrapperComponent, isStandalone: true, selector: "cide-lyt-header-wrapper", viewQueries: [{ propertyName: "triggerTemplate", first: true, predicate: ["triggerTemplate"], descendants: true }, { propertyName: "financialYearTriggerTemplate", first: true, predicate: ["financialYearTriggerTemplate"], descendants: true }, { propertyName: "academicYearTriggerTemplate", first: true, predicate: ["academicYearTriggerTemplate"], descendants: true }, { propertyName: "notificationTriggerTemplate", first: true, predicate: ["notificationTriggerTemplate"], descendants: true }, { 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 <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-w-full tw-max-w-[480px] tw-min-w-[440px] tw-bg-white tw-rounded-2xl tw-shadow-2xl tw-overflow-hidden tw-flex tw-flex-col tw-max-h-[600px]\">\n <!-- Header -->\n <div class=\"tw-px-5 tw-py-4 tw-bg-white tw-flex tw-justify-between tw-items-center\">\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <h3 class=\"tw-m-0 tw-text-lg tw-font-semibold tw-text-gray-900\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"tw-bg-gray-200 tw-text-gray-700 tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-semibold\">{{ unreadCount() }}</span>\n }\n </div>\n <button \n type=\"button\" \n class=\"tw-bg-transparent tw-border-none tw-p-1.5 tw-cursor-pointer tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded-lg tw-transition-all tw-duration-200 hover:tw-bg-gray-100 hover:tw-text-gray-600\"\n (click)=\"closeNotificationDropdown($event)\">\n <cide-ele-icon class=\"!tw-text-xl\">close</cide-ele-icon>\n </button>\n </div>\n\n <!-- Notifications List -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-p-0 [&::-webkit-scrollbar]:tw-w-1.5 [&::-webkit-scrollbar-track]:tw-bg-transparent [&::-webkit-scrollbar-thumb]:tw-bg-gray-300 [&::-webkit-scrollbar-thumb]:tw-rounded-full\">\n @if (notifications().length === 0) {\n <div class=\"tw-py-16 tw-px-6 tw-text-center\">\n <cide-ele-icon class=\"!tw-text-6xl !tw-text-gray-300 tw-mb-4\">notifications_off</cide-ele-icon>\n <p class=\"tw-m-0 tw-text-base tw-text-gray-500 tw-font-medium\">No notifications</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-5 tw-py-4 tw-cursor-pointer tw-transition-all tw-duration-200 tw-relative tw-gap-4 tw-border-b tw-border-b-gray-100 hover:tw-bg-gray-50\"\n [class.tw-bg-white]=\"!isNotificationRead(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <!-- Icon/Avatar -->\n <div class=\"tw-flex-shrink-0 tw-relative\">\n <div class=\"tw-w-12 tw-h-12 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-md\">\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-2xl !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-3 tw-h-3 tw-bg-green-500 tw-rounded-full tw-border-2 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-3 tw-mb-1\">\n <div class=\"tw-flex-1\">\n <h4 class=\"tw-m-0 tw-text-sm tw-font-bold tw-text-gray-900 tw-mb-0.5\">\n {{ getNotificationName(notif) }}<span class=\"tw-font-normal tw-text-gray-600\">{{ getNotificationAction(notif) }}</span>\n </h4>\n <p class=\"tw-m-0 tw-text-xs tw-text-gray-500\">{{ getFullTime(notif.timestamp) }}</p>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-2 tw-flex-shrink-0\">\n <span class=\"tw-text-xs tw-text-gray-500 tw-whitespace-nowrap\">{{ getTimeAgo(notif.timestamp) }}</span>\n @if (!isNotificationRead(notif)) {\n <div class=\"tw-w-2 tw-h-2 tw-rounded-full tw-bg-blue-500\"></div>\n }\n </div>\n </div>\n \n <!-- Message -->\n @if (notif.message && notif.message !== notif.title) {\n <p class=\"tw-m-0 tw-mt-2 tw-text-sm tw-text-gray-700 tw-leading-relaxed\">\n {{ notif.message }}\n </p>\n }\n \n <!-- Comment -->\n @if (notif.data?.comment) {\n <div class=\"tw-mt-3 tw-py-3 tw-px-4 tw-bg-gray-50 tw-rounded-lg tw-border-l-4 tw-border-l-blue-500\">\n <p class=\"tw-m-0 tw-text-sm tw-text-gray-700 tw-leading-relaxed tw-italic\">{{ notif.data.comment }}</p>\n </div>\n }\n \n <!-- File -->\n @if (notif.data?.file) {\n <div class=\"tw-mt-3 tw-py-3 tw-px-4 tw-bg-gray-50 tw-border tw-border-gray-200 tw-rounded-lg tw-flex tw-items-center tw-gap-3\">\n <div class=\"tw-w-10 tw-h-10 tw-bg-blue-100 tw-rounded-lg tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\n <span class=\"tw-text-xs tw-font-bold tw-text-blue-600\">{{ 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-sm tw-font-semibold tw-text-gray-900 tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap\">{{ notif.data.file.name }}</p>\n <p class=\"tw-m-0 tw-text-xs tw-text-gray-500\">{{ notif.data.file.size }}</p>\n </div>\n <cide-ele-icon class=\"tw-text-gray-400 tw-cursor-pointer tw-transition-colors tw-duration-200 tw-flex-shrink-0 hover:tw-text-blue-500\">download</cide-ele-icon>\n </div>\n }\n \n <!-- Action Buttons -->\n @if (notif.action_label) {\n <div class=\"tw-mt-3 tw-flex tw-gap-2\">\n @if (notif.action_label.toLowerCase().includes('decline')) {\n <button type=\"button\" class=\"tw-py-2 tw-px-5 tw-border tw-border-gray-300 tw-bg-white tw-rounded-lg tw-text-sm tw-font-medium tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-700 hover:tw-bg-gray-50 hover:tw-border-gray-400\">Decline</button>\n }\n @if (notif.action_label.toLowerCase().includes('accept')) {\n <button type=\"button\" class=\"tw-py-2 tw-px-5 tw-border tw-border-blue-600 tw-bg-blue-600 tw-rounded-lg tw-text-sm tw-font-medium tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-white hover:tw-bg-blue-700 hover:tw-border-blue-700\">Accept</button>\n }\n </div>\n }\n </div>\n </div>\n }\n }\n </div>\n </div>\n </ng-template>\n\n <div class=\"header-divider\"></div>\n\n <!-- Profile with Dropdown -->\n <div class=\"header-icon user-profile\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"profileItems\" [config]=\"profileConfig\"\n [triggerTemplate]=\"triggerTemplate\"\n (itemClick)=\"onProfileClick($event)\">\n <ng-template #triggerTemplate>\n @if (appStateService.currentUser()?.user_photo_id_cyfm) {\n <div class=\"profile-avatar\">\n <img cideEleFileImage [fileId]=\"(appStateService.currentUser()?.user_photo_id_cyfm || '')\"\n [altText]=\"'User Profile Photo'\" class=\"tw-w-full tw-h-full tw-object-cover tw-rounded-full\">\n </div>\n } @else {\n <div class=\"profile-avatar\">\n <cide-ele-icon name=\"person\" class=\"tw-w-6 tw-h-6 tw-text-white\"></cide-ele-icon>\n </div>\n }\n </ng-template>\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">My Account</div>\n </div>\n </div>\n</header>", styles: [".cide-lyt-header{display:flex;align-items:center;justify-content:space-between;background:linear-gradient(to right,#fffffff2,#f9fafbf2);box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:20;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgba(229,231,235,.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-logo-container{height:100%;display:flex;align-items:center;padding:.5rem 0;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);border-radius:8px;outline:none}.header-logo-container img{height:30px;max-height:100%;transition:all .3s ease;border-radius:5px;overflow:hidden;box-shadow:0 1px 4px #0000000d}.header-logo-container:hover img{transform:scale(1.03);filter:brightness(1.05);box-shadow:0 2px 6px #00000014}.header-logo-container:after{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:linear-gradient(to bottom right,#fff0,#ffffff4d,#fff0);transform:rotate(30deg);opacity:0;transition:transform .6s ease,opacity .6s ease;pointer-events:none}.header-logo-container:hover:after,.header-logo-container:focus:after{opacity:1;transform:rotate(30deg) translate(50%,50%)}.header-search-container{flex-grow:1;max-width:600px;margin:0 2rem;position:relative;transition:all .3s ease}::ng-deep .header-search-container #cide_lyt_header_search{width:100%;background-color:#f9fafbcc;border-radius:20px!important;transition:all .3s ease;overflow:visible;transform:translateZ(0)}::ng-deep .header-search-container #cide_lyt_header_search:hover{box-shadow:0 3px 12px #00000014;background-color:#fff;transform:translateY(-1px)}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-input{background-color:transparent;font-size:.85rem!important;letter-spacing:.01em}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:#6b7280b3!important;font-size:1.1rem!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within{transform:translateY(-1px) scale(1.01)}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-input{border-color:#3b82f6!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-leading-icon{color:#3b82f6!important}.header-icons-container{display:flex;align-items:center;gap:1rem}.header-icon{position:relative;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-dropdown-container{position:relative;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-icon:before{content:\"\";position:absolute;inset:0;background-color:#3b82f61a;border-radius:.5rem;opacity:0;transform:scale(.8);transition:all .2s cubic-bezier(.4,0,.2,1)}.header-icon:hover:before{opacity:1;transform:scale(1)}.header-icon:hover{color:#3b82f6}.header-icon:active{transform:scale(.95)}.header-tooltip{position:absolute;bottom:-26px;left:50%;transform:translate(-50%);background-color:#374151e6;color:#fff;padding:.25rem .6rem;border-radius:.25rem;font-size:.7rem;white-space:nowrap;opacity:0;pointer-events:none;transition:all .2s cubic-bezier(.4,0,.2,1);z-index:1000;box-shadow:0 2px 5px #0003;letter-spacing:.01em;will-change:transform,opacity}.header-tooltip:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:5px;border-style:solid;border-color:transparent transparent rgba(55,65,81,.9) transparent}.header-icon:hover .header-tooltip{opacity:1;transform:translate(-50%) translateY(0)}.header-badge{position:absolute;top:0;right:0;min-width:16px;height:16px;border-radius:8px;background-color:#ef4444;color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 1px 3px #ef44444d;font-weight:600;z-index:2;transition:all .2s ease}.header-icon:hover .header-badge{transform:scale(1.1)}.header-divider{height:20px;width:1px;background-color:#e5e7ebcc;margin:0 6px}.header-year-dropdown-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.header-year-pill{position:relative;display:flex;align-items:center;padding:.25rem .625rem;background:linear-gradient(135deg,#3b82f61a,#2563eb26);border:1px solid rgba(59,130,246,.3);border-radius:9999px;color:#2563eb;font-size:.6875rem;font-weight:600;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;white-space:nowrap;box-shadow:0 1px 2px #3b82f61a;min-height:22px;height:22px;line-height:1}.header-year-pill:hover{background:linear-gradient(135deg,#3b82f626,#2563eb33);border-color:#3b82f666;transform:translateY(-1px);box-shadow:0 2px 6px #3b82f626}.header-year-pill-text{max-width:180px;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em;line-height:1;display:inline-block}::ng-deep .header-dropdown-container .dropdown-trigger{background:transparent!important;border:none!important;border-radius:0!important;padding:0!important;width:100%!important;height:100%!important;min-width:auto!important;box-shadow:none!important;display:flex!important;align-items:center!important;justify-content:center!important;transition:none!important;cursor:pointer!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover{background:transparent!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover .header-year-pill{background:linear-gradient(135deg,#3b82f626,#2563eb33)!important;border-color:#3b82f666!important;transform:translateY(-1px)!important;box-shadow:0 2px 6px #3b82f626!important}::ng-deep .header-dropdown-container .dropdown-trigger:focus,::ng-deep .header-dropdown-container .dropdown-trigger:focus-visible,::ng-deep .header-dropdown-container .dropdown-trigger:active{outline:none!important;box-shadow:0 2px 6px #3b82f626!important}.profile-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;font-size:.75rem;font-weight:600;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #2563eb33;transition:all .2s cubic-bezier(.4,0,.2,1);letter-spacing:-.5px;cursor:pointer;border:2px solid transparent}.profile-avatar:hover,.header-icon:hover .profile-avatar{transform:scale(1.08);box-shadow:0 3px 8px #2563eb4d;border-color:#3b82f64d}::ng-deep .user-profile .dropdown-trigger{background:transparent!important;border:none!important;padding:0!important;width:auto!important;height:auto!important;border-radius:0!important}::ng-deep .user-profile .dropdown-trigger:hover{background:transparent!important}::ng-deep .user-profile .dropdown-trigger:focus,::ng-deep .user-profile .dropdown-trigger:focus-visible,::ng-deep .user-profile .dropdown-trigger:active{outline:none!important;box-shadow:none!important}.header-avatar{width:36px;height:36px;border-radius:50%;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);border:2px solid transparent;box-shadow:0 2px 4px #0000001a}.header-avatar:hover{border-color:#3b82f6;transform:scale(1.05);box-shadow:0 3px 6px #3b82f64d}@media (max-width: 768px){.header-search-container{margin:0 1rem}.header-icons-container{gap:.5rem}}@media (max-width: 640px){.header-search-container{max-width:200px;margin:0 .5rem}}\n"], dependencies: [{ kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "size"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleDropdownComponent, selector: "cide-ele-dropdown", inputs: ["items", "config", "triggerTemplate", "menuTemplate"], outputs: ["itemClick", "dropdownToggle"] }, { kind: "directive", type: CideEleFileImageDirective, selector: "[cideEleFileImage]", inputs: ["fileId", "altText"] }] });
|
|
2392
2392
|
}
|
|
2393
2393
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytHeaderWrapperComponent, decorators: [{
|
|
2394
2394
|
type: Component,
|
|
2395
2395
|
args: [{ selector: 'cide-lyt-header-wrapper', imports: [CideInputComponent, CommonModule, CideIconComponent,
|
|
2396
|
-
CideEleDropdownComponent, CideEleFileImageDirective], template: "<header id=\"cide-lyt-header-wrapper\" class=\"cide-lyt-header tw-w-full tw-select-none cide-lyt-header-wrapper-hide\">\n <!-- Logo Section -->\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <div class=\"header-logo-container tw-flex tw-items-center tw-gap-3 tw-cursor-pointer\" (click)=\"onLogoClick()\"\n (keydown.enter)=\"onLogoClick()\" (keydown.space)=\"onLogoClick()\" tabindex=\"0\" role=\"button\"\n aria-label=\"Navigate to home\" title=\"Click to go to control panel home\">\n @if (appStateService.activeEntity()?.syen_photo_id_cyfm) {\n <img cideEleFileImage [fileId]=\"(appStateService.activeEntity()?.syen_photo_id_cyfm || '')\"\n [altText]=\"'Entity Logo'\" class=\"tw-w-8 tw-h-8 tw-object-contain\">\n } @else {\n <cide-ele-icon name=\"business\" class=\"tw-w-8 tw-h-8 tw-text-blue-600\"></cide-ele-icon>\n }\n\n </div>\n @if (appStateService.activeEntity()?.syen_name) {\n <span\n class=\"tw-text-md tw-font-semibold tw-text-blue-600 hover:tw-text-blue-800 tw-cursor-pointer sm:block tw-transition-colors tw-duration-200 hover:tw-underline\"\n (click)=\"onEntityNameClick()\" title=\"Click to switch entity\">\n {{ appStateService.activeEntity()?.syen_name }}\n </span>\n }\n </div>\n <!-- Search Section -->\n <div class=\"header-search-container\">\n <cide-ele-input id=\"cide_lyt_header_search\" placeholder=\"Search...\" leadingIcon=\"search\"\n size=\"md\"></cide-ele-input>\n </div>\n\n <!-- Icons Section -->\n <div class=\"header-icons-container\">\n <!-- Financial Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"financialYearItems\" [config]=\"financialYearConfig\"\n [triggerTemplate]=\"financialYearTriggerTemplate\"\n (itemClick)=\"onFinancialYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Financial Year</div>\n </div>\n \n <ng-template #financialYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">calendar_today</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentFinancialYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Academic Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"academicYearItems\" [config]=\"academicYearConfig\"\n [triggerTemplate]=\"academicYearTriggerTemplate\"\n (itemClick)=\"onAcademicYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Academic Year</div>\n </div>\n \n <ng-template #academicYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">school</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentAcademicYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Notifications Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown \n #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-w-full tw-max-w-[360px] tw-min-w-[340px] tw-bg-white tw-rounded-lg tw-shadow-lg tw-overflow-hidden tw-flex tw-flex-col tw-max-h-[85vh]\">\n <!-- Header -->\n <div class=\"tw-px-4 tw-py-2.5 tw-bg-white tw-border-b tw-border-b-gray-100 tw-flex tw-justify-between tw-items-center tw-sticky tw-top-0 tw-z-10\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <h3 class=\"tw-m-0 tw-text-sm tw-font-semibold tw-text-gray-900\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"tw-bg-gray-500 tw-text-white tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-[10px] tw-font-medium tw-min-w-4 tw-text-center tw-leading-none\">{{ unreadCount() }}</span>\n }\n </div>\n <button \n type=\"button\" \n class=\"tw-bg-transparent tw-border-none tw-p-0.5 tw-cursor-pointer tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded tw-transition-all tw-duration-150 tw-w-6 tw-h-6 hover:tw-bg-gray-100 hover:tw-text-gray-600\"\n (click)=\"closeNotificationDropdown($event)\">\n <cide-ele-icon class=\"!tw-text-base\">close</cide-ele-icon>\n </button>\n </div>\n\n <!-- Notifications List -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-p-0 [&::-webkit-scrollbar]:tw-w-1 [&::-webkit-scrollbar-track]:tw-bg-transparent [&::-webkit-scrollbar-thumb]:tw-bg-gray-300 [&::-webkit-scrollbar-thumb]:tw-rounded-full [&::-webkit-scrollbar-thumb]:hover:tw-bg-gray-400\">\n @if (notifications().length === 0) {\n <div class=\"tw-py-10 tw-px-4 tw-text-center\">\n <cide-ele-icon class=\"!tw-text-4xl !tw-text-gray-300 tw-mb-2\">notifications_off</cide-ele-icon>\n <p class=\"tw-m-0 tw-text-xs tw-text-gray-400 tw-font-medium\">No notifications</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.5 tw-cursor-pointer tw-transition-colors tw-duration-150 tw-relative tw-gap-2 tw-border-b tw-border-b-gray-50 hover:tw-bg-gray-50/50\"\n [class.tw-bg-white]=\"!isNotificationRead(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <!-- Profile Avatar -->\n <div class=\"tw-flex-shrink-0 tw-w-8 tw-h-8 tw-rounded-full tw-overflow-hidden tw-bg-gray-200 tw-flex tw-items-center tw-justify-center tw-relative\">\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 <div class=\"tw-w-full tw-h-full tw-bg-gradient-to-br tw-from-indigo-500 tw-to-purple-600 tw-text-white tw-flex tw-items-center tw-justify-center\">\n <cide-ele-icon class=\"!tw-text-sm !tw-text-white\">{{ getNotificationIcon(notif.type) }}</cide-ele-icon>\n </div>\n }\n </div>\n\n <!-- Content -->\n <div class=\"tw-flex-1 tw-min-w-0 tw-flex tw-flex-col tw-gap-0 tw-pr-3\">\n <div class=\"tw-flex tw-items-start tw-justify-between tw-gap-2\">\n <div class=\"tw-flex-1 tw-min-w-0\">\n <div class=\"tw-text-xs tw-text-gray-900 tw-leading-tight\">\n <span class=\"tw-font-semibold tw-text-gray-900\">{{ getNotificationName(notif) }}</span>\n <span class=\"tw-font-normal tw-text-gray-600\">{{ getNotificationAction(notif) }}</span>\n </div>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1.5 tw-flex-shrink-0\">\n <div class=\"tw-text-[10px] tw-text-gray-400 tw-whitespace-nowrap\">{{ getTimeAgo(notif.timestamp) }}</div>\n @if (!isNotificationRead(notif)) {\n <div class=\"tw-w-1.5 tw-h-1.5 tw-rounded-full tw-bg-blue-500 tw-flex-shrink-0\"></div>\n }\n </div>\n </div>\n <div class=\"tw-text-[10px] tw-text-gray-500 tw-mt-0.5\">{{ getFullTime(notif.timestamp) }}</div>\n @if (notif.message && notif.message !== notif.title) {\n <div class=\"tw-mt-1 tw-text-xs tw-text-gray-600 tw-leading-relaxed\">\n {{ notif.message }}\n </div>\n }\n @if (notif.data?.comment) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2.5 tw-bg-gray-50 tw-rounded tw-border-l-2 tw-border-l-blue-500 tw-text-[11px] tw-text-gray-700 tw-leading-relaxed\">\n {{ notif.data.comment }}\n </div>\n }\n @if (notif.data?.file) {\n <div class=\"tw-mt-1.5 tw-py-1.5 tw-px-2 tw-bg-gray-50 tw-border tw-border-gray-200 tw-rounded tw-flex tw-items-center tw-gap-1.5\">\n <div class=\"tw-w-7 tw-h-7 tw-bg-gray-300 tw-rounded tw-flex tw-items-center tw-justify-center tw-text-[9px] tw-font-semibold tw-text-white tw-flex-shrink-0\">{{ getFileIcon(notif.data.file.type) }}</div>\n <div class=\"tw-flex-1 tw-min-w-0\">\n <div class=\"tw-text-[11px] tw-font-medium tw-text-gray-900 tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap\">{{ notif.data.file.name }}</div>\n <div class=\"tw-text-[9px] tw-text-gray-500\">{{ notif.data.file.size }}</div>\n </div>\n <cide-ele-icon class=\"tw-text-gray-400 tw-cursor-pointer tw-transition-colors tw-duration-150 tw-flex-shrink-0 tw-text-xs hover:tw-text-blue-500\">download</cide-ele-icon>\n </div>\n }\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-0.5 tw-px-2.5 tw-border tw-border-gray-200 tw-bg-white tw-rounded tw-text-[11px] tw-font-medium tw-cursor-pointer tw-transition-all tw-duration-150 tw-text-gray-600 hover:tw-bg-gray-50 hover:tw-border-gray-300\">Decline</button>\n }\n @if (notif.action_label.toLowerCase().includes('accept')) {\n <button type=\"button\" class=\"tw-py-0.5 tw-px-2.5 tw-border tw-border-blue-500 tw-bg-blue-500 tw-rounded tw-text-[11px] tw-font-medium tw-cursor-pointer tw-transition-all tw-duration-150 tw-text-white hover:tw-bg-blue-600 hover:tw-border-blue-600\">Accept</button>\n }\n </div>\n }\n </div>\n </div>\n }\n }\n </div>\n </div>\n </ng-template>\n\n <div class=\"header-divider\"></div>\n\n <!-- Profile with Dropdown -->\n <div class=\"header-icon user-profile\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"profileItems\" [config]=\"profileConfig\"\n [triggerTemplate]=\"triggerTemplate\"\n (itemClick)=\"onProfileClick($event)\">\n <ng-template #triggerTemplate>\n @if (appStateService.currentUser()?.user_photo_id_cyfm) {\n <div class=\"profile-avatar\">\n <img cideEleFileImage [fileId]=\"(appStateService.currentUser()?.user_photo_id_cyfm || '')\"\n [altText]=\"'User Profile Photo'\" class=\"tw-w-full tw-h-full tw-object-cover tw-rounded-full\">\n </div>\n } @else {\n <div class=\"profile-avatar\">\n <cide-ele-icon name=\"person\" class=\"tw-w-6 tw-h-6 tw-text-white\"></cide-ele-icon>\n </div>\n }\n </ng-template>\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">My Account</div>\n </div>\n </div>\n</header>", styles: [".cide-lyt-header{display:flex;align-items:center;justify-content:space-between;background:linear-gradient(to right,#fffffff2,#f9fafbf2);box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:20;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgba(229,231,235,.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-logo-container{height:100%;display:flex;align-items:center;padding:.5rem 0;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);border-radius:8px;outline:none}.header-logo-container img{height:30px;max-height:100%;transition:all .3s ease;border-radius:5px;overflow:hidden;box-shadow:0 1px 4px #0000000d}.header-logo-container:hover img{transform:scale(1.03);filter:brightness(1.05);box-shadow:0 2px 6px #00000014}.header-logo-container:after{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:linear-gradient(to bottom right,#fff0,#ffffff4d,#fff0);transform:rotate(30deg);opacity:0;transition:transform .6s ease,opacity .6s ease;pointer-events:none}.header-logo-container:hover:after,.header-logo-container:focus:after{opacity:1;transform:rotate(30deg) translate(50%,50%)}.header-search-container{flex-grow:1;max-width:600px;margin:0 2rem;position:relative;transition:all .3s ease}::ng-deep .header-search-container #cide_lyt_header_search{width:100%;background-color:#f9fafbcc;border-radius:20px!important;transition:all .3s ease;overflow:visible;transform:translateZ(0)}::ng-deep .header-search-container #cide_lyt_header_search:hover{box-shadow:0 3px 12px #00000014;background-color:#fff;transform:translateY(-1px)}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-input{background-color:transparent;font-size:.85rem!important;letter-spacing:.01em}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:#6b7280b3!important;font-size:1.1rem!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within{transform:translateY(-1px) scale(1.01)}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-input{border-color:#3b82f6!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-leading-icon{color:#3b82f6!important}.header-icons-container{display:flex;align-items:center;gap:1rem}.header-icon{position:relative;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-dropdown-container{position:relative;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-icon:before{content:\"\";position:absolute;inset:0;background-color:#3b82f61a;border-radius:.5rem;opacity:0;transform:scale(.8);transition:all .2s cubic-bezier(.4,0,.2,1)}.header-icon:hover:before{opacity:1;transform:scale(1)}.header-icon:hover{color:#3b82f6}.header-icon:active{transform:scale(.95)}.header-tooltip{position:absolute;bottom:-26px;left:50%;transform:translate(-50%);background-color:#374151e6;color:#fff;padding:.25rem .6rem;border-radius:.25rem;font-size:.7rem;white-space:nowrap;opacity:0;pointer-events:none;transition:all .2s cubic-bezier(.4,0,.2,1);z-index:1000;box-shadow:0 2px 5px #0003;letter-spacing:.01em;will-change:transform,opacity}.header-tooltip:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:5px;border-style:solid;border-color:transparent transparent rgba(55,65,81,.9) transparent}.header-icon:hover .header-tooltip{opacity:1;transform:translate(-50%) translateY(0)}.header-badge{position:absolute;top:0;right:0;min-width:16px;height:16px;border-radius:8px;background-color:#ef4444;color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 1px 3px #ef44444d;font-weight:600;z-index:2;transition:all .2s ease}.header-icon:hover .header-badge{transform:scale(1.1)}.header-divider{height:20px;width:1px;background-color:#e5e7ebcc;margin:0 6px}.header-year-dropdown-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.header-year-pill{position:relative;display:flex;align-items:center;padding:.25rem .625rem;background:linear-gradient(135deg,#3b82f61a,#2563eb26);border:1px solid rgba(59,130,246,.3);border-radius:9999px;color:#2563eb;font-size:.6875rem;font-weight:600;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;white-space:nowrap;box-shadow:0 1px 2px #3b82f61a;min-height:22px;height:22px;line-height:1}.header-year-pill:hover{background:linear-gradient(135deg,#3b82f626,#2563eb33);border-color:#3b82f666;transform:translateY(-1px);box-shadow:0 2px 6px #3b82f626}.header-year-pill-text{max-width:180px;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em;line-height:1;display:inline-block}::ng-deep .header-dropdown-container .dropdown-trigger{background:transparent!important;border:none!important;border-radius:0!important;padding:0!important;width:100%!important;height:100%!important;min-width:auto!important;box-shadow:none!important;display:flex!important;align-items:center!important;justify-content:center!important;transition:none!important;cursor:pointer!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover{background:transparent!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover .header-year-pill{background:linear-gradient(135deg,#3b82f626,#2563eb33)!important;border-color:#3b82f666!important;transform:translateY(-1px)!important;box-shadow:0 2px 6px #3b82f626!important}::ng-deep .header-dropdown-container .dropdown-trigger:focus,::ng-deep .header-dropdown-container .dropdown-trigger:focus-visible,::ng-deep .header-dropdown-container .dropdown-trigger:active{outline:none!important;box-shadow:0 2px 6px #3b82f626!important}.profile-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;font-size:.75rem;font-weight:600;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #2563eb33;transition:all .2s cubic-bezier(.4,0,.2,1);letter-spacing:-.5px;cursor:pointer;border:2px solid transparent}.profile-avatar:hover,.header-icon:hover .profile-avatar{transform:scale(1.08);box-shadow:0 3px 8px #2563eb4d;border-color:#3b82f64d}::ng-deep .user-profile .dropdown-trigger{background:transparent!important;border:none!important;padding:0!important;width:auto!important;height:auto!important;border-radius:0!important}::ng-deep .user-profile .dropdown-trigger:hover{background:transparent!important}::ng-deep .user-profile .dropdown-trigger:focus,::ng-deep .user-profile .dropdown-trigger:focus-visible,::ng-deep .user-profile .dropdown-trigger:active{outline:none!important;box-shadow:none!important}.header-avatar{width:36px;height:36px;border-radius:50%;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);border:2px solid transparent;box-shadow:0 2px 4px #0000001a}.header-avatar:hover{border-color:#3b82f6;transform:scale(1.05);box-shadow:0 3px 6px #3b82f64d}@media (max-width: 768px){.header-search-container{margin:0 1rem}.header-icons-container{gap:.5rem}}@media (max-width: 640px){.header-search-container{max-width:200px;margin:0 .5rem}}\n"] }]
|
|
2396
|
+
CideEleDropdownComponent, CideEleFileImageDirective], template: "<header id=\"cide-lyt-header-wrapper\" class=\"cide-lyt-header tw-w-full tw-select-none cide-lyt-header-wrapper-hide\">\n <!-- Logo Section -->\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <div class=\"header-logo-container tw-flex tw-items-center tw-gap-3 tw-cursor-pointer\" (click)=\"onLogoClick()\"\n (keydown.enter)=\"onLogoClick()\" (keydown.space)=\"onLogoClick()\" tabindex=\"0\" role=\"button\"\n aria-label=\"Navigate to home\" title=\"Click to go to control panel home\">\n @if (appStateService.activeEntity()?.syen_photo_id_cyfm) {\n <img cideEleFileImage [fileId]=\"(appStateService.activeEntity()?.syen_photo_id_cyfm || '')\"\n [altText]=\"'Entity Logo'\" class=\"tw-w-8 tw-h-8 tw-object-contain\">\n } @else {\n <cide-ele-icon name=\"business\" class=\"tw-w-8 tw-h-8 tw-text-blue-600\"></cide-ele-icon>\n }\n\n </div>\n @if (appStateService.activeEntity()?.syen_name) {\n <span\n class=\"tw-text-md tw-font-semibold tw-text-blue-600 hover:tw-text-blue-800 tw-cursor-pointer sm:block tw-transition-colors tw-duration-200 hover:tw-underline\"\n (click)=\"onEntityNameClick()\" title=\"Click to switch entity\">\n {{ appStateService.activeEntity()?.syen_name }}\n </span>\n }\n </div>\n <!-- Search Section -->\n <div class=\"header-search-container\">\n <cide-ele-input id=\"cide_lyt_header_search\" placeholder=\"Search...\" leadingIcon=\"search\"\n size=\"md\"></cide-ele-input>\n </div>\n\n <!-- Icons Section -->\n <div class=\"header-icons-container\">\n <!-- Financial Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"financialYearItems\" [config]=\"financialYearConfig\"\n [triggerTemplate]=\"financialYearTriggerTemplate\"\n (itemClick)=\"onFinancialYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Financial Year</div>\n </div>\n \n <ng-template #financialYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">calendar_today</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentFinancialYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Academic Year Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"academicYearItems\" [config]=\"academicYearConfig\"\n [triggerTemplate]=\"academicYearTriggerTemplate\"\n (itemClick)=\"onAcademicYearClick($event)\">\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">Academic Year</div>\n </div>\n \n <ng-template #academicYearTriggerTemplate let-isOpen=\"isOpen\">\n <div class=\"header-year-pill\">\n <cide-ele-icon size=\"2xs\" type=\"none\" class=\"tw-mr-1\">school</cide-ele-icon>\n <span class=\"header-year-pill-text\">{{ currentAcademicYearName() }}</span>\n </div>\n </ng-template>\n\n <!-- Notifications Dropdown -->\n <div class=\"header-dropdown-container\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown \n #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-w-full tw-max-w-[480px] tw-min-w-[440px] tw-bg-white tw-rounded-2xl tw-shadow-2xl tw-overflow-hidden tw-flex tw-flex-col tw-max-h-[600px]\">\n <!-- Header -->\n <div class=\"tw-px-5 tw-py-4 tw-bg-white tw-flex tw-justify-between tw-items-center\">\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <h3 class=\"tw-m-0 tw-text-lg tw-font-semibold tw-text-gray-900\">Notifications</h3>\n @if (unreadCount() > 0) {\n <span class=\"tw-bg-gray-200 tw-text-gray-700 tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-semibold\">{{ unreadCount() }}</span>\n }\n </div>\n <button \n type=\"button\" \n class=\"tw-bg-transparent tw-border-none tw-p-1.5 tw-cursor-pointer tw-text-gray-400 tw-flex tw-items-center tw-justify-center tw-rounded-lg tw-transition-all tw-duration-200 hover:tw-bg-gray-100 hover:tw-text-gray-600\"\n (click)=\"closeNotificationDropdown($event)\">\n <cide-ele-icon class=\"!tw-text-xl\">close</cide-ele-icon>\n </button>\n </div>\n\n <!-- Notifications List -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-p-0 [&::-webkit-scrollbar]:tw-w-1.5 [&::-webkit-scrollbar-track]:tw-bg-transparent [&::-webkit-scrollbar-thumb]:tw-bg-gray-300 [&::-webkit-scrollbar-thumb]:tw-rounded-full\">\n @if (notifications().length === 0) {\n <div class=\"tw-py-16 tw-px-6 tw-text-center\">\n <cide-ele-icon class=\"!tw-text-6xl !tw-text-gray-300 tw-mb-4\">notifications_off</cide-ele-icon>\n <p class=\"tw-m-0 tw-text-base tw-text-gray-500 tw-font-medium\">No notifications</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-5 tw-py-4 tw-cursor-pointer tw-transition-all tw-duration-200 tw-relative tw-gap-4 tw-border-b tw-border-b-gray-100 hover:tw-bg-gray-50\"\n [class.tw-bg-white]=\"!isNotificationRead(notif)\"\n (click)=\"onNotificationItemClick(notif)\">\n <!-- Icon/Avatar -->\n <div class=\"tw-flex-shrink-0 tw-relative\">\n <div class=\"tw-w-12 tw-h-12 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-md\">\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-2xl !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-3 tw-h-3 tw-bg-green-500 tw-rounded-full tw-border-2 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-3 tw-mb-1\">\n <div class=\"tw-flex-1\">\n <h4 class=\"tw-m-0 tw-text-sm tw-font-bold tw-text-gray-900 tw-mb-0.5\">\n {{ getNotificationName(notif) }}<span class=\"tw-font-normal tw-text-gray-600\">{{ getNotificationAction(notif) }}</span>\n </h4>\n <p class=\"tw-m-0 tw-text-xs tw-text-gray-500\">{{ getFullTime(notif.timestamp) }}</p>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-2 tw-flex-shrink-0\">\n <span class=\"tw-text-xs tw-text-gray-500 tw-whitespace-nowrap\">{{ getTimeAgo(notif.timestamp) }}</span>\n @if (!isNotificationRead(notif)) {\n <div class=\"tw-w-2 tw-h-2 tw-rounded-full tw-bg-blue-500\"></div>\n }\n </div>\n </div>\n \n <!-- Message -->\n @if (notif.message && notif.message !== notif.title) {\n <p class=\"tw-m-0 tw-mt-2 tw-text-sm tw-text-gray-700 tw-leading-relaxed\">\n {{ notif.message }}\n </p>\n }\n \n <!-- Comment -->\n @if (notif.data?.comment) {\n <div class=\"tw-mt-3 tw-py-3 tw-px-4 tw-bg-gray-50 tw-rounded-lg tw-border-l-4 tw-border-l-blue-500\">\n <p class=\"tw-m-0 tw-text-sm tw-text-gray-700 tw-leading-relaxed tw-italic\">{{ notif.data.comment }}</p>\n </div>\n }\n \n <!-- File -->\n @if (notif.data?.file) {\n <div class=\"tw-mt-3 tw-py-3 tw-px-4 tw-bg-gray-50 tw-border tw-border-gray-200 tw-rounded-lg tw-flex tw-items-center tw-gap-3\">\n <div class=\"tw-w-10 tw-h-10 tw-bg-blue-100 tw-rounded-lg tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\n <span class=\"tw-text-xs tw-font-bold tw-text-blue-600\">{{ 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-sm tw-font-semibold tw-text-gray-900 tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap\">{{ notif.data.file.name }}</p>\n <p class=\"tw-m-0 tw-text-xs tw-text-gray-500\">{{ notif.data.file.size }}</p>\n </div>\n <cide-ele-icon class=\"tw-text-gray-400 tw-cursor-pointer tw-transition-colors tw-duration-200 tw-flex-shrink-0 hover:tw-text-blue-500\">download</cide-ele-icon>\n </div>\n }\n \n <!-- Action Buttons -->\n @if (notif.action_label) {\n <div class=\"tw-mt-3 tw-flex tw-gap-2\">\n @if (notif.action_label.toLowerCase().includes('decline')) {\n <button type=\"button\" class=\"tw-py-2 tw-px-5 tw-border tw-border-gray-300 tw-bg-white tw-rounded-lg tw-text-sm tw-font-medium tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-700 hover:tw-bg-gray-50 hover:tw-border-gray-400\">Decline</button>\n }\n @if (notif.action_label.toLowerCase().includes('accept')) {\n <button type=\"button\" class=\"tw-py-2 tw-px-5 tw-border tw-border-blue-600 tw-bg-blue-600 tw-rounded-lg tw-text-sm tw-font-medium tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-white hover:tw-bg-blue-700 hover:tw-border-blue-700\">Accept</button>\n }\n </div>\n }\n </div>\n </div>\n }\n }\n </div>\n </div>\n </ng-template>\n\n <div class=\"header-divider\"></div>\n\n <!-- Profile with Dropdown -->\n <div class=\"header-icon user-profile\" (mouseenter)=\"updateTooltipPosition($event)\">\n <cide-ele-dropdown [items]=\"profileItems\" [config]=\"profileConfig\"\n [triggerTemplate]=\"triggerTemplate\"\n (itemClick)=\"onProfileClick($event)\">\n <ng-template #triggerTemplate>\n @if (appStateService.currentUser()?.user_photo_id_cyfm) {\n <div class=\"profile-avatar\">\n <img cideEleFileImage [fileId]=\"(appStateService.currentUser()?.user_photo_id_cyfm || '')\"\n [altText]=\"'User Profile Photo'\" class=\"tw-w-full tw-h-full tw-object-cover tw-rounded-full\">\n </div>\n } @else {\n <div class=\"profile-avatar\">\n <cide-ele-icon name=\"person\" class=\"tw-w-6 tw-h-6 tw-text-white\"></cide-ele-icon>\n </div>\n }\n </ng-template>\n </cide-ele-dropdown>\n <div class=\"header-tooltip\">My Account</div>\n </div>\n </div>\n</header>", styles: [".cide-lyt-header{display:flex;align-items:center;justify-content:space-between;background:linear-gradient(to right,#fffffff2,#f9fafbf2);box-shadow:0 2px 8px #00000008;padding:0 1rem;position:relative;z-index:20;transition:all .3s cubic-bezier(.4,0,.2,1);will-change:transform;border-bottom:1px solid rgba(229,231,235,.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.header-logo-container{height:100%;display:flex;align-items:center;padding:.5rem 0;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);border-radius:8px;outline:none}.header-logo-container img{height:30px;max-height:100%;transition:all .3s ease;border-radius:5px;overflow:hidden;box-shadow:0 1px 4px #0000000d}.header-logo-container:hover img{transform:scale(1.03);filter:brightness(1.05);box-shadow:0 2px 6px #00000014}.header-logo-container:after{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:linear-gradient(to bottom right,#fff0,#ffffff4d,#fff0);transform:rotate(30deg);opacity:0;transition:transform .6s ease,opacity .6s ease;pointer-events:none}.header-logo-container:hover:after,.header-logo-container:focus:after{opacity:1;transform:rotate(30deg) translate(50%,50%)}.header-search-container{flex-grow:1;max-width:600px;margin:0 2rem;position:relative;transition:all .3s ease}::ng-deep .header-search-container #cide_lyt_header_search{width:100%;background-color:#f9fafbcc;border-radius:20px!important;transition:all .3s ease;overflow:visible;transform:translateZ(0)}::ng-deep .header-search-container #cide_lyt_header_search:hover{box-shadow:0 3px 12px #00000014;background-color:#fff;transform:translateY(-1px)}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-input{background-color:transparent;font-size:.85rem!important;letter-spacing:.01em}::ng-deep .header-search-container #cide_lyt_header_search .cide-input-leading-icon{color:#6b7280b3!important;font-size:1.1rem!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within{transform:translateY(-1px) scale(1.01)}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-input{border-color:#3b82f6!important}::ng-deep .header-search-container #cide_lyt_header_search:focus-within .cide-input-leading-icon{color:#3b82f6!important}.header-icons-container{display:flex;align-items:center;gap:1rem}.header-icon{position:relative;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-dropdown-container{position:relative;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;color:#374151;border-radius:.4rem;margin:0 2px}.header-icon:before{content:\"\";position:absolute;inset:0;background-color:#3b82f61a;border-radius:.5rem;opacity:0;transform:scale(.8);transition:all .2s cubic-bezier(.4,0,.2,1)}.header-icon:hover:before{opacity:1;transform:scale(1)}.header-icon:hover{color:#3b82f6}.header-icon:active{transform:scale(.95)}.header-tooltip{position:absolute;bottom:-26px;left:50%;transform:translate(-50%);background-color:#374151e6;color:#fff;padding:.25rem .6rem;border-radius:.25rem;font-size:.7rem;white-space:nowrap;opacity:0;pointer-events:none;transition:all .2s cubic-bezier(.4,0,.2,1);z-index:1000;box-shadow:0 2px 5px #0003;letter-spacing:.01em;will-change:transform,opacity}.header-tooltip:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:5px;border-style:solid;border-color:transparent transparent rgba(55,65,81,.9) transparent}.header-icon:hover .header-tooltip{opacity:1;transform:translate(-50%) translateY(0)}.header-badge{position:absolute;top:0;right:0;min-width:16px;height:16px;border-radius:8px;background-color:#ef4444;color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 1px 3px #ef44444d;font-weight:600;z-index:2;transition:all .2s ease}.header-icon:hover .header-badge{transform:scale(1.1)}.header-divider{height:20px;width:1px;background-color:#e5e7ebcc;margin:0 6px}.header-year-dropdown-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.header-year-pill{position:relative;display:flex;align-items:center;padding:.25rem .625rem;background:linear-gradient(135deg,#3b82f61a,#2563eb26);border:1px solid rgba(59,130,246,.3);border-radius:9999px;color:#2563eb;font-size:.6875rem;font-weight:600;transition:all .2s cubic-bezier(.4,0,.2,1);cursor:pointer;white-space:nowrap;box-shadow:0 1px 2px #3b82f61a;min-height:22px;height:22px;line-height:1}.header-year-pill:hover{background:linear-gradient(135deg,#3b82f626,#2563eb33);border-color:#3b82f666;transform:translateY(-1px);box-shadow:0 2px 6px #3b82f626}.header-year-pill-text{max-width:180px;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em;line-height:1;display:inline-block}::ng-deep .header-dropdown-container .dropdown-trigger{background:transparent!important;border:none!important;border-radius:0!important;padding:0!important;width:100%!important;height:100%!important;min-width:auto!important;box-shadow:none!important;display:flex!important;align-items:center!important;justify-content:center!important;transition:none!important;cursor:pointer!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover{background:transparent!important}::ng-deep .header-dropdown-container .dropdown-trigger:hover .header-year-pill{background:linear-gradient(135deg,#3b82f626,#2563eb33)!important;border-color:#3b82f666!important;transform:translateY(-1px)!important;box-shadow:0 2px 6px #3b82f626!important}::ng-deep .header-dropdown-container .dropdown-trigger:focus,::ng-deep .header-dropdown-container .dropdown-trigger:focus-visible,::ng-deep .header-dropdown-container .dropdown-trigger:active{outline:none!important;box-shadow:0 2px 6px #3b82f626!important}.profile-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;font-size:.75rem;font-weight:600;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #2563eb33;transition:all .2s cubic-bezier(.4,0,.2,1);letter-spacing:-.5px;cursor:pointer;border:2px solid transparent}.profile-avatar:hover,.header-icon:hover .profile-avatar{transform:scale(1.08);box-shadow:0 3px 8px #2563eb4d;border-color:#3b82f64d}::ng-deep .user-profile .dropdown-trigger{background:transparent!important;border:none!important;padding:0!important;width:auto!important;height:auto!important;border-radius:0!important}::ng-deep .user-profile .dropdown-trigger:hover{background:transparent!important}::ng-deep .user-profile .dropdown-trigger:focus,::ng-deep .user-profile .dropdown-trigger:focus-visible,::ng-deep .user-profile .dropdown-trigger:active{outline:none!important;box-shadow:none!important}.header-avatar{width:36px;height:36px;border-radius:50%;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);border:2px solid transparent;box-shadow:0 2px 4px #0000001a}.header-avatar:hover{border-color:#3b82f6;transform:scale(1.05);box-shadow:0 3px 6px #3b82f64d}@media (max-width: 768px){.header-search-container{margin:0 1rem}.header-icons-container{gap:.5rem}}@media (max-width: 640px){.header-search-container{max-width:200px;margin:0 .5rem}}\n"] }]
|
|
2397
2397
|
}], ctorParameters: () => [], propDecorators: { triggerTemplate: [{
|
|
2398
2398
|
type: ViewChild,
|
|
2399
2399
|
args: ['triggerTemplate']
|
|
@@ -3611,8 +3611,8 @@ class CideLytSidedrawerWrapperComponent {
|
|
|
3611
3611
|
}
|
|
3612
3612
|
ngOnInit() {
|
|
3613
3613
|
// Initialize the component map (You'd likely populate this from a config or service)
|
|
3614
|
-
this.componentMap['drowar_notes'] = () => import('./cloud-ide-layout-sidedrawer-notes.component-
|
|
3615
|
-
this.componentMap['drawer_theme'] = () => import('./cloud-ide-layout-drawer-theme.component-
|
|
3614
|
+
this.componentMap['drowar_notes'] = () => import('./cloud-ide-layout-sidedrawer-notes.component-CsFwJdTC.mjs').then(m => m.CideLytSidedrawerNotesComponent);
|
|
3615
|
+
this.componentMap['drawer_theme'] = () => import('./cloud-ide-layout-drawer-theme.component-DMMPXwHK.mjs').then(m => m.CideLytDrawerThemeComponent);
|
|
3616
3616
|
}
|
|
3617
3617
|
async loadComponent(configFor) {
|
|
3618
3618
|
console.log('🔍 SIDEDRAWER - Loading component:', configFor, 'Current tab:', this.currentTabId);
|
|
@@ -4135,7 +4135,7 @@ const layoutControlPannelChildRoutes = [{
|
|
|
4135
4135
|
},
|
|
4136
4136
|
{
|
|
4137
4137
|
path: "home",
|
|
4138
|
-
loadComponent: () => import('./cloud-ide-layout-home-wrapper.component-
|
|
4138
|
+
loadComponent: () => import('./cloud-ide-layout-home-wrapper.component-CqXQq2xa.mjs').then(c => c.CideLytHomeWrapperComponent),
|
|
4139
4139
|
canActivate: [authGuard],
|
|
4140
4140
|
data: {
|
|
4141
4141
|
reuseTab: true, // For CustomRouteReuseStrategy
|
|
@@ -5703,4 +5703,4 @@ var floatingEntityRightsSharing_component = /*#__PURE__*/Object.freeze({
|
|
|
5703
5703
|
*/
|
|
5704
5704
|
|
|
5705
5705
|
export { AppStateHelperService as A, CideLytSharedWrapperComponent as C, ENVIRONMENT_CONFIG as E, CideLytSidebarService as a, CideLytRequestService as b, CideLytSidedrawerService as c, CideLytThemeService as d, AppStateService as e, CloudIdeLayoutService as f, CloudIdeLayoutComponent as g, CideLytSharedService as h, layoutControlPannelChildRoutes as i, CustomRouteReuseStrategy as j, CideLytUserStatusService as k, layoutRoutes as l, CacheManagerService as m, CideLytFileManagerService as n, CideLytFloatingEntityRightsSharingComponent as o, processThemeVariable as p, CideLytFloatingEntityRightsSharingService as q, setCSSVariable as s, themeFactory as t };
|
|
5706
|
-
//# sourceMappingURL=cloud-ide-layout-cloud-ide-layout-
|
|
5706
|
+
//# sourceMappingURL=cloud-ide-layout-cloud-ide-layout-B3UJ3l6Z.mjs.map
|