@aggdirect/coolmap 5.0.11 → 5.0.13

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.
@@ -192,7 +192,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
192
192
  class JobDetailsComponent {
193
193
  modalOpen = input(false, ...(ngDevMode ? [{ debugName: "modalOpen" }] : []));
194
194
  routeData = input(null, ...(ngDevMode ? [{ debugName: "routeData" }] : []));
195
- noBackdrop = input(false, ...(ngDevMode ? [{ debugName: "noBackdrop" }] : []));
196
195
  modalOpenChange = new EventEmitter();
197
196
  dragX = signal(0, ...(ngDevMode ? [{ debugName: "dragX" }] : []));
198
197
  dragY = signal(0, ...(ngDevMode ? [{ debugName: "dragY" }] : []));
@@ -239,12 +238,12 @@ class JobDetailsComponent {
239
238
  this.isDragging = false;
240
239
  }
241
240
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: JobDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
242
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: JobDetailsComponent, isStandalone: true, selector: "lib-job-details", inputs: { modalOpen: { classPropertyName: "modalOpen", publicName: "modalOpen", isSignal: true, isRequired: false, transformFunction: null }, routeData: { classPropertyName: "routeData", publicName: "routeData", isSignal: true, isRequired: false, transformFunction: null }, noBackdrop: { classPropertyName: "noBackdrop", publicName: "noBackdrop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modalOpenChange: "modalOpenChange" }, host: { listeners: { "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUp()" } }, ngImport: i0, template: "@if (modalOpen()) {\n<div \n class=\"z-[11] xl:z-[100] bottom-0 lg:left-[350px] fixed lg:absolute inset-0 overflow-y-auto\"\n [class.pointer-events-none]=\"noBackdrop()\"\n>\n @if (!noBackdrop()) {\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n }\n <div class=\"flex min-h-full lg:items-end lg:justify-start items-center justify-center p-3\">\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl w-[350px] pointer-events-auto\"\n [style.transform]=\"'translate(' + dragX() + 'px, ' + dragY() + 'px)'\"\n [style.will-change]=\"'transform'\"\n (click)=\"$event.stopPropagation()\"\n \n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b cursor-move border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg select-none\" (mousedown)=\"startDrag($event)\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Job Details\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors text-gray-500\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[50vh] overflow-y-auto p-2\">\n <div class=\"stats-row\">\n <div class=\"stat-item completed\">\n <span class=\"stat-count\">{{ routeData()?.values?.Done || 0 }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item pending\">\n <span class=\"stat-count\">{{ routeData()?.values?.Ongoing || 0 }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item active\">\n <span class=\"stat-count\">{{ routeData()?.values?.Open || 0 }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n <div\n class=\"location-flow bg-gray-100 dark:bg-slate-900 border border-gray-300 dark:border-slate-700 px-2 py-2 rounded-lg mt-4\"\n >\n <span class=\"pickup truncate block\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-green-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Pickup: {{ routeData()?.pickup_location || 'N/A' }}\n </span>\n <span class=\"delivery truncate block mt-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-blue-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Delivery: {{ routeData()?.delivery_location || 'N/A' }}\n </span>\n </div>\n <div class=\"device-info mt-2\">\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Jobcode</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.order_number || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Project Name</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.project || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Job Type</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Material</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.material || 'General Freight' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer Contact</span>\n <span class=\"font-medium\">{{ routeData()?.customer_contact || 'None' }}</span>\n </div>\n <div class=\"flex justify-between py-2 text-xs\">\n <span class=\"text-gray-500 dark:text-slate-500\">Delivery Contact</span>\n <span class=\"font-medium\">{{ routeData()?.delivery_contact || 'None' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".stats-row{display:flex;align-items:center;gap:30px;font-size:12px;margin:0 10px 0 60px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .delivery{display:flex;align-items:center;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
241
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: JobDetailsComponent, isStandalone: true, selector: "lib-job-details", inputs: { modalOpen: { classPropertyName: "modalOpen", publicName: "modalOpen", isSignal: true, isRequired: false, transformFunction: null }, routeData: { classPropertyName: "routeData", publicName: "routeData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modalOpenChange: "modalOpenChange" }, host: { listeners: { "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUp()" } }, ngImport: i0, template: "@if (modalOpen()) {\n<div \n class=\"z-[11] xl:z-[100] bottom-0 lg:left-[350px] fixed lg:absolute inset-0 overflow-y-auto pointer-events-none\"\n>\n <div class=\"flex min-h-full lg:items-end lg:justify-start items-center justify-center p-3\">\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl w-[350px] pointer-events-auto\"\n [style.transform]=\"'translate(' + dragX() + 'px, ' + dragY() + 'px)'\"\n [style.will-change]=\"'transform'\"\n (click)=\"$event.stopPropagation()\"\n \n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b cursor-move border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg select-none\" (mousedown)=\"startDrag($event)\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Job Details\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors text-gray-500\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[50vh] overflow-y-auto p-2\">\n <div class=\"stats-row\">\n <div class=\"stat-item completed\">\n <span class=\"stat-count\">{{ routeData()?.values?.Done || 0 }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item pending\">\n <span class=\"stat-count\">{{ routeData()?.values?.Ongoing || 0 }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item active\">\n <span class=\"stat-count\">{{ routeData()?.values?.Open || 0 }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n <div\n class=\"location-flow bg-gray-100 dark:bg-slate-900 border border-gray-300 dark:border-slate-700 px-2 py-2 rounded-lg mt-4\"\n >\n <span class=\"pickup truncate block\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-green-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Pickup: {{ routeData()?.pickup_location || 'N/A' }}\n </span>\n <span class=\"delivery truncate block mt-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-blue-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Delivery: {{ routeData()?.delivery_location || 'N/A' }}\n </span>\n </div>\n <div class=\"device-info mt-2\">\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Jobcode</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.order_number || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Project Name</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.project || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Job Type</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Material</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.material || 'General Freight' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer Contact</span>\n <span class=\"font-medium\">{{ routeData()?.customer_contact || 'None' }}</span>\n </div>\n <div class=\"flex justify-between py-2 text-xs\">\n <span class=\"text-gray-500 dark:text-slate-500\">Delivery Contact</span>\n <span class=\"font-medium\">{{ routeData()?.delivery_contact || 'None' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".stats-row{display:flex;align-items:center;gap:30px;font-size:12px;margin:0 10px 0 60px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .delivery{display:flex;align-items:center;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
243
242
  }
244
243
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: JobDetailsComponent, decorators: [{
245
244
  type: Component,
246
- args: [{ selector: 'lib-job-details', standalone: true, imports: [LucideAngularModule], template: "@if (modalOpen()) {\n<div \n class=\"z-[11] xl:z-[100] bottom-0 lg:left-[350px] fixed lg:absolute inset-0 overflow-y-auto\"\n [class.pointer-events-none]=\"noBackdrop()\"\n>\n @if (!noBackdrop()) {\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n }\n <div class=\"flex min-h-full lg:items-end lg:justify-start items-center justify-center p-3\">\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl w-[350px] pointer-events-auto\"\n [style.transform]=\"'translate(' + dragX() + 'px, ' + dragY() + 'px)'\"\n [style.will-change]=\"'transform'\"\n (click)=\"$event.stopPropagation()\"\n \n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b cursor-move border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg select-none\" (mousedown)=\"startDrag($event)\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Job Details\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors text-gray-500\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[50vh] overflow-y-auto p-2\">\n <div class=\"stats-row\">\n <div class=\"stat-item completed\">\n <span class=\"stat-count\">{{ routeData()?.values?.Done || 0 }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item pending\">\n <span class=\"stat-count\">{{ routeData()?.values?.Ongoing || 0 }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item active\">\n <span class=\"stat-count\">{{ routeData()?.values?.Open || 0 }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n <div\n class=\"location-flow bg-gray-100 dark:bg-slate-900 border border-gray-300 dark:border-slate-700 px-2 py-2 rounded-lg mt-4\"\n >\n <span class=\"pickup truncate block\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-green-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Pickup: {{ routeData()?.pickup_location || 'N/A' }}\n </span>\n <span class=\"delivery truncate block mt-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-blue-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Delivery: {{ routeData()?.delivery_location || 'N/A' }}\n </span>\n </div>\n <div class=\"device-info mt-2\">\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Jobcode</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.order_number || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Project Name</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.project || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Job Type</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Material</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.material || 'General Freight' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer Contact</span>\n <span class=\"font-medium\">{{ routeData()?.customer_contact || 'None' }}</span>\n </div>\n <div class=\"flex justify-between py-2 text-xs\">\n <span class=\"text-gray-500 dark:text-slate-500\">Delivery Contact</span>\n <span class=\"font-medium\">{{ routeData()?.delivery_contact || 'None' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".stats-row{display:flex;align-items:center;gap:30px;font-size:12px;margin:0 10px 0 60px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .delivery{display:flex;align-items:center;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"] }]
247
- }], ctorParameters: () => [], propDecorators: { modalOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "modalOpen", required: false }] }], routeData: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeData", required: false }] }], noBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "noBackdrop", required: false }] }], modalOpenChange: [{
245
+ args: [{ selector: 'lib-job-details', standalone: true, imports: [LucideAngularModule], template: "@if (modalOpen()) {\n<div \n class=\"z-[11] xl:z-[100] bottom-0 lg:left-[350px] fixed lg:absolute inset-0 overflow-y-auto pointer-events-none\"\n>\n <div class=\"flex min-h-full lg:items-end lg:justify-start items-center justify-center p-3\">\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl w-[350px] pointer-events-auto\"\n [style.transform]=\"'translate(' + dragX() + 'px, ' + dragY() + 'px)'\"\n [style.will-change]=\"'transform'\"\n (click)=\"$event.stopPropagation()\"\n \n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b cursor-move border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg select-none\" (mousedown)=\"startDrag($event)\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Job Details\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors text-gray-500\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[50vh] overflow-y-auto p-2\">\n <div class=\"stats-row\">\n <div class=\"stat-item completed\">\n <span class=\"stat-count\">{{ routeData()?.values?.Done || 0 }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item pending\">\n <span class=\"stat-count\">{{ routeData()?.values?.Ongoing || 0 }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item active\">\n <span class=\"stat-count\">{{ routeData()?.values?.Open || 0 }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n <div\n class=\"location-flow bg-gray-100 dark:bg-slate-900 border border-gray-300 dark:border-slate-700 px-2 py-2 rounded-lg mt-4\"\n >\n <span class=\"pickup truncate block\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-green-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Pickup: {{ routeData()?.pickup_location || 'N/A' }}\n </span>\n <span class=\"delivery truncate block mt-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-blue-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Delivery: {{ routeData()?.delivery_location || 'N/A' }}\n </span>\n </div>\n <div class=\"device-info mt-2\">\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Jobcode</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.order_number || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Project Name</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.project || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Job Type</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Material</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.material || 'General Freight' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer Contact</span>\n <span class=\"font-medium\">{{ routeData()?.customer_contact || 'None' }}</span>\n </div>\n <div class=\"flex justify-between py-2 text-xs\">\n <span class=\"text-gray-500 dark:text-slate-500\">Delivery Contact</span>\n <span class=\"font-medium\">{{ routeData()?.delivery_contact || 'None' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".stats-row{display:flex;align-items:center;gap:30px;font-size:12px;margin:0 10px 0 60px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .delivery{display:flex;align-items:center;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"] }]
246
+ }], ctorParameters: () => [], propDecorators: { modalOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "modalOpen", required: false }] }], routeData: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeData", required: false }] }], modalOpenChange: [{
248
247
  type: Output
249
248
  }], onMouseMove: [{
250
249
  type: HostListener,
@@ -272,7 +271,6 @@ class JobCodeComponent {
272
271
  collapsible = true;
273
272
  routes = [];
274
273
  selectedRouteIds = [];
275
- isLoading = true;
276
274
  routeSelect = new EventEmitter();
277
275
  collapsed = false;
278
276
  // New Signal States
@@ -299,6 +297,9 @@ class JobCodeComponent {
299
297
  this.driverListcollapse.set(this.collapsed);
300
298
  }
301
299
  }
300
+ get listLoading() {
301
+ return this.coolmapService.isLoading();
302
+ }
302
303
  calculateStatusPercentage(type, route) {
303
304
  const values = route?.values || { Done: 0, Ongoing: 0, Open: 0 };
304
305
  const total = (values.Done || 0) + (values.Ongoing || 0) + (values.Open || 0);
@@ -337,11 +338,11 @@ class JobCodeComponent {
337
338
  }
338
339
  }
339
340
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: JobCodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
340
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: JobCodeComponent, isStandalone: true, selector: "lib-job-code", inputs: { listMode: "listMode", collapsible: "collapsible", routes: "routes", selectedRouteIds: "selectedRouteIds", isLoading: "isLoading" }, outputs: { routeSelect: "routeSelect" }, host: { listeners: { "document:keydown.escape": "icons()" } }, ngImport: i0, template: "<div\n class=\"cards-list-container\"\n [class.floating]=\"listMode === 'floating'\"\n [class.sidebar]=\"listMode === 'sidebar'\"\n [class.inline]=\"listMode === 'inline'\"\n [class.collapsed]=\"collapsed\"\n>\n <div class=\"list-header\">\n <div class=\"header-title\">\n <span class=\"title-text\">Routes</span>\n <span class=\"routes-count\">({{ routes.length || 0 }})</span>\n </div>\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse()\"\n [title]=\"collapsed ? 'Expand' : 'Collapse'\"\n >\n @if (collapsed) {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n }\n </button>\n </div>\n @if (!collapsed) {\n <div class=\"cards-scroll-container\" #scrollContainer>\n @if (isLoading) {\n <div class=\"list-loader\">\n <lucide-icon [img]=\"icons.LoaderCircle\" [size]=\"32\" class=\"animate-spin text-amber-500\"></lucide-icon>\n </div>\n }\n @if(!isLoading && routes && routes.length){\n <div class=\"cards-list\">\n @for (route of routes; track $index) {\n <div class=\"card-wrapper\" (click)=\"toggleRouteSelection(route)\">\n <div\n class=\"route-card bg-white dark:bg-slate-800 border transition-all duration-200\"\n [class.border-brand-blue]=\"selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.border-gray-300]=\"!selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.dark:border-slate-700]=\"!selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.selected]=\"selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n >\n <div class=\"task-header justify-between\">\n <span class=\"job-code\">{{ route.order_number || 'N/A' }}</span>\n <div class=\"flex gap-2\">\n <div class=\"statusunit text-white\" [ngClass]=\"route.unit || ''\">{{ route.unit?.charAt(0) || 'U' }}</div>\n @if (config.repository !== 'customer') {\n <div\n class=\"statusunit bg-slate-900 dark:bg-white text-white dark:text-black flex items-center justify-center cursor-pointer hover:opacity-80\"\n (click)=\"showDriverModal = true; toggleCollapse(); $event.stopPropagation()\"\n >\n <lucide-icon [img]=\"icons.CarFront\" [size]=\"15\"></lucide-icon>\n </div>\n }\n <div\n class=\"text-black dark:text-white flex items-center justify-center cursor-pointer hover:opacity-80\"\n (click)=\"openDetail(route, true); $event.stopPropagation()\"\n (mouseenter)=\"openDetail(route, false)\"\n (mouseleave)=\"closeDetail(true)\"\n >\n <lucide-icon [img]=\"icons.Info\" [size]=\"20\"></lucide-icon>\n </div>\n </div>\n </div>\n <div class=\"customer-name font-semibold truncate\">{{ route.customer_name }}</div>\n <div class=\"material-info truncate text-gray-600 dark:text-gray-300\">{{ route.project || 'No Project' }}</div>\n <div class=\"location-flow mt-2 text-sm flex items-center gap-2\">\n <span class=\"pickup flex items-center gap-1 truncate max-w-[40%] text-green-600 dark:text-green-400\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n {{ (route.pickup_location || '').split('|')[0] || 'Unknown' }}\n </span>\n <span class=\"arrow text-gray-400\">\u2192</span>\n <span class=\"delivery truncate max-w-[40%] text-brand-blue\">{{ (route.delivery_location || '').split('|')[0] || 'Unknown' }}</span>\n </div>\n <div class=\"material-info mt-2 truncate font-medium\">{{ route.material || '' }}</div>\n <div class=\"driver-row-4 mt-3 flex items-center gap-2\">\n <div class=\"progress-bar flex-1 h-1.5 bg-gray-200 dark:bg-slate-700 rounded-full overflow-hidden flex\">\n <div class=\"progress-segment completed h-full bg-green-500 transition-all duration-300\" [style.width.%]=\"calculateStatusPercentage('done', route)\"></div>\n <div class=\"progress-segment ongoing h-full transition-all duration-300\" [style.backgroundColor]=\"'#fc0'\" [style.width.%]=\"calculateStatusPercentage('ongoing', route)\"></div>\n <div class=\"progress-segment open h-full bg-gray-300 dark:bg-slate-600 transition-all duration-300\" [style.width.%]=\"calculateStatusPercentage('open', route)\"></div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n } @else if(!isLoading && coolmapService.isDataFetched() && (!routes || routes.length === 0)) {\n <div class=\"empty-state\">\n <div class=\"text-gray-600 dark:text-gray-400 mt-2 text-center\">No Job code found.</div>\n </div>\n }\n </div>\n }\n</div>\n<lib-driver-list\n [(modalOpen)]=\"showDriverModal\"\n [driverListcollapse]=\"driverListcollapse()\"\n></lib-driver-list>\n<lib-job-details \n [modalOpen]=\"showDetailModal\" \n (modalOpenChange)=\"$event ? null : closeDetail(false)\" \n [routeData]=\"selectedJobDetail()\" \n [noBackdrop]=\"!isClickTriggered\"\n></lib-job-details>\n", styles: [":host{display:block}.cards-list-container{display:flex;flex-direction:column;height:100%;background:var(--bg-primary, white)}.cards-list-container.floating{position:absolute;top:12px;left:12px;width:280px;max-height:calc(100% - 24px);border-radius:12px;box-shadow:0 4px 24px #00000026;z-index:100;overflow:hidden}.cards-list-container.floating.collapsed{width:48px}.cards-list-container.sidebar{width:100%;border-right:1px solid var(--border-color, #e2e8f0)}.cards-list-container.inline{width:160px;min-width:160px;border-right:1px solid var(--border-color, #e2e8f0)}:host-context(.dark) .cards-list-container{background-color:#1e293b}:host-context(.dark) .cards-list-container.sidebar,:host-context(.dark) .cards-list-container.inline{border-color:#334155}.list-header{display:flex;align-items:center;justify-content:space-between;padding:12px;border-bottom:1px solid var(--border-color, #e2e8f0);background:var(--bg-secondary, #f8fafc)}:host-context(.dark) .list-header{background-color:#0f172a;border-color:#334155}.collapsed .list-header{padding:12px 8px;justify-content:center}.header-title{display:flex;align-items:center;gap:6px}.collapsed .header-title{display:none}.title-text{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .title-text{color:#f1f5f9}.routes-count{font-size:12px;color:var(--text-secondary, #64748b)}.collapse-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:transparent;color:var(--text-secondary, #64748b);cursor:pointer;border-radius:6px;transition:all .15s ease}.collapse-btn:hover{background:var(--hover-bg, #e2e8f0);color:var(--text-primary, #1e293b)}:host-context(.dark) .collapse-btn:hover{background-color:#334155;color:#f1f5f9}.cards-scroll-container{flex:1;overflow-y:auto;overflow-x:hidden}.cards-list{display:flex;flex-direction:column;gap:8px;padding:8px}.card-wrapper{border-radius:8px;transition:all .2s ease}.route-card{position:relative;padding:6px 10px;display:flex;flex-direction:column;gap:2px;border-radius:8px;cursor:pointer;transition:all .15s ease;min-height:72px}.route-card:hover{border-color:var(--accent-color, #3b82f6);box-shadow:0 2px 8px #00000014}.route-card.selected{border-color:var(--accent-color, #3b82f6);background:#3b82f60d}.task-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.job-code{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .job-code{color:#f1f5f9}.customer-name{font-size:12px;color:var(--text-secondary, #64748b);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.material-info{font-size:11px;color:var(--text-tertiary, #94a3b8);margin-bottom:6px;font-weight:500}.location-flow{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .arrow{color:var(--text-tertiary, #94a3b8)}.location-flow .delivery{color:#ef4444}.driver-row-4{display:flex;align-items:center;gap:4px;margin-top:2px}.progress-bar{display:flex;gap:2px}.progress-segment{height:6px;border-radius:2px;position:relative;cursor:pointer}.progress-segment.completed{background:#22c55e}.progress-segment.in_progress{background:#f59e0b}.progress-segment.pending{background:#cbd5e1}.progress-segment.incomplete{background:#ef4444}.progress-segment:after{content:attr(data-tooltip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);background:#1e293b;color:#fff;padding:6px 10px;border-radius:6px;font-size:10px;white-space:pre-line;min-width:120px;max-width:180px;box-shadow:0 3px 10px #0003;z-index:1000;opacity:0;visibility:hidden;transition:opacity .15s ease;pointer-events:none}.progress-segment:hover:after{opacity:1;visibility:visible}.task-count{font-size:10px;font-weight:600;color:var(--text-secondary, #64748b);min-width:24px;text-align:right}.on-time-indicator{font-size:10px;color:#22c55e}.on-time-indicator.late{color:#ef4444}.statusunit{border-radius:30px;font-size:12px;text-transform:capitalize;font-weight:600;width:20px;height:20px;text-align:center;line-height:20px}.statusunit.Ton{background:#22c55e}.statusunit.Load{background:#3b82f6}.statusunit.Hourly{background:#f59e0b}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:50;border-radius:0 0 12px 12px}:host-context(.dark) .list-loader{background:#0f172a66}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: DriverListComponent, selector: "lib-driver-list", inputs: ["modalOpen", "driverListcollapse"], outputs: ["modalOpenChange"] }, { kind: "component", type: JobDetailsComponent, selector: "lib-job-details", inputs: ["modalOpen", "routeData", "noBackdrop"], outputs: ["modalOpenChange"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
341
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: JobCodeComponent, isStandalone: true, selector: "lib-job-code", inputs: { listMode: "listMode", collapsible: "collapsible", routes: "routes", selectedRouteIds: "selectedRouteIds" }, outputs: { routeSelect: "routeSelect" }, host: { listeners: { "document:keydown.escape": "icons()" } }, ngImport: i0, template: "<div\n class=\"cards-list-container\"\n [class.floating]=\"listMode === 'floating'\"\n [class.sidebar]=\"listMode === 'sidebar'\"\n [class.inline]=\"listMode === 'inline'\"\n [class.collapsed]=\"collapsed\"\n>\n <div class=\"list-header\">\n <div class=\"header-title\">\n <span class=\"title-text\">Routes</span>\n <span class=\"routes-count\">({{ routes.length || 0 }})</span>\n </div>\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse()\"\n [title]=\"collapsed ? 'Expand' : 'Collapse'\"\n >\n @if (collapsed) {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n }\n </button>\n </div>\n @if (!collapsed) {\n <div class=\"cards-scroll-container\" #scrollContainer>\n @if (listLoading) {\n <div class=\"list-loader\">\n <lucide-icon [img]=\"icons.LoaderCircle\" [size]=\"32\" class=\"animate-spin text-amber-500\"></lucide-icon>\n </div>\n }\n @if(!listLoading && routes && routes.length){\n <div class=\"cards-list\">\n @for (route of routes; track $index) {\n <div class=\"card-wrapper\" (click)=\"toggleRouteSelection(route)\">\n <div\n class=\"route-card bg-white dark:bg-slate-800 border transition-all duration-200\"\n [class.border-brand-blue]=\"selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.border-gray-300]=\"!selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.dark:border-slate-700]=\"!selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.selected]=\"selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n >\n <div class=\"task-header justify-between\">\n <span class=\"job-code\">{{ route.order_number || 'N/A' }}</span>\n <div class=\"flex gap-2\">\n <div class=\"statusunit text-white\" [ngClass]=\"route.unit || ''\">{{ route.unit?.charAt(0) || 'U' }}</div>\n @if (config.repository !== 'customer') {\n <div\n class=\"statusunit bg-slate-900 dark:bg-white text-white dark:text-black flex items-center justify-center cursor-pointer hover:opacity-80\"\n (click)=\"showDriverModal = true; toggleCollapse(); $event.stopPropagation()\"\n >\n <lucide-icon [img]=\"icons.CarFront\" [size]=\"15\"></lucide-icon>\n </div>\n }\n <div\n class=\"text-black dark:text-white flex items-center justify-center cursor-pointer hover:opacity-80\"\n (click)=\"openDetail(route, true); $event.stopPropagation()\"\n (mouseenter)=\"openDetail(route, false)\"\n (mouseleave)=\"closeDetail(true)\"\n >\n <lucide-icon [img]=\"icons.Info\" [size]=\"20\"></lucide-icon>\n </div>\n </div>\n </div>\n <div class=\"customer-name font-semibold truncate\">{{ route.customer_name }}</div>\n <div class=\"material-info truncate text-gray-600 dark:text-gray-300\">{{ route.project || 'No Project' }}</div>\n <div class=\"location-flow mt-2 text-sm flex items-center gap-2\">\n <span class=\"pickup flex items-center gap-1 truncate max-w-[40%] text-green-600 dark:text-green-400\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n {{ (route.pickup_location || '').split('|')[0] || 'Unknown' }}\n </span>\n <span class=\"arrow text-gray-400\">\u2192</span>\n <span class=\"delivery truncate max-w-[40%] text-brand-blue\">{{ (route.delivery_location || '').split('|')[0] || 'Unknown' }}</span>\n </div>\n <div class=\"material-info mt-2 truncate font-medium\">{{ route.material || '' }}</div>\n <div class=\"driver-row-4 mt-3 flex items-center gap-2\">\n <div class=\"progress-bar flex-1 h-1.5 bg-gray-200 dark:bg-slate-700 rounded-full overflow-hidden flex\">\n <div class=\"progress-segment completed h-full bg-green-500 transition-all duration-300\" [style.width.%]=\"calculateStatusPercentage('done', route)\"></div>\n <div class=\"progress-segment ongoing h-full transition-all duration-300\" [style.backgroundColor]=\"'#fc0'\" [style.width.%]=\"calculateStatusPercentage('ongoing', route)\"></div>\n <div class=\"progress-segment open h-full bg-gray-300 dark:bg-slate-600 transition-all duration-300\" [style.width.%]=\"calculateStatusPercentage('open', route)\"></div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n } @else if(!listLoading && coolmapService.isDataFetched() && (!routes || routes.length === 0)) {\n <div class=\"empty-state\">\n <div class=\"text-gray-600 dark:text-gray-400 mt-2 text-center\">No Job code found.</div>\n </div>\n }\n </div>\n }\n</div>\n<lib-driver-list\n [(modalOpen)]=\"showDriverModal\"\n [driverListcollapse]=\"driverListcollapse()\"\n></lib-driver-list>\n<lib-job-details \n [modalOpen]=\"showDetailModal\" \n (modalOpenChange)=\"$event ? null : closeDetail(false)\" \n [routeData]=\"selectedJobDetail()\" \n></lib-job-details>\n", styles: [":host{display:block}.cards-list-container{display:flex;flex-direction:column;height:100%;background:var(--bg-primary, white)}.cards-list-container.floating{position:absolute;top:12px;left:12px;width:280px;max-height:calc(100% - 24px);border-radius:12px;box-shadow:0 4px 24px #00000026;z-index:100;overflow:hidden}.cards-list-container.floating.collapsed{width:48px}.cards-list-container.sidebar{width:100%;border-right:1px solid var(--border-color, #e2e8f0)}.cards-list-container.inline{width:160px;min-width:160px;border-right:1px solid var(--border-color, #e2e8f0)}:host-context(.dark) .cards-list-container{background-color:#1e293b}:host-context(.dark) .cards-list-container.sidebar,:host-context(.dark) .cards-list-container.inline{border-color:#334155}.list-header{display:flex;align-items:center;justify-content:space-between;padding:12px;border-bottom:1px solid var(--border-color, #e2e8f0);background:var(--bg-secondary, #f8fafc)}:host-context(.dark) .list-header{background-color:#0f172a;border-color:#334155}.collapsed .list-header{padding:12px 8px;justify-content:center}.header-title{display:flex;align-items:center;gap:6px}.collapsed .header-title{display:none}.title-text{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .title-text{color:#f1f5f9}.routes-count{font-size:12px;color:var(--text-secondary, #64748b)}.collapse-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:transparent;color:var(--text-secondary, #64748b);cursor:pointer;border-radius:6px;transition:all .15s ease}.collapse-btn:hover{background:var(--hover-bg, #e2e8f0);color:var(--text-primary, #1e293b)}:host-context(.dark) .collapse-btn:hover{background-color:#334155;color:#f1f5f9}.cards-scroll-container{flex:1;overflow-y:auto;overflow-x:hidden}.cards-list{display:flex;flex-direction:column;gap:8px;padding:8px}.card-wrapper{border-radius:8px;transition:all .2s ease}.route-card{position:relative;padding:6px 10px;display:flex;flex-direction:column;gap:2px;border-radius:8px;cursor:pointer;transition:all .15s ease;min-height:72px}.route-card:hover{border-color:var(--accent-color, #3b82f6);box-shadow:0 2px 8px #00000014}.route-card.selected{border-color:var(--accent-color, #3b82f6);background:#3b82f60d}.task-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.job-code{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .job-code{color:#f1f5f9}.customer-name{font-size:12px;color:var(--text-secondary, #64748b);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.material-info{font-size:11px;color:var(--text-tertiary, #94a3b8);margin-bottom:6px;font-weight:500}.location-flow{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .arrow{color:var(--text-tertiary, #94a3b8)}.location-flow .delivery{color:#ef4444}.driver-row-4{display:flex;align-items:center;gap:4px;margin-top:2px}.progress-bar{display:flex;gap:2px}.progress-segment{height:6px;border-radius:2px;position:relative;cursor:pointer}.progress-segment.completed{background:#22c55e}.progress-segment.in_progress{background:#f59e0b}.progress-segment.pending{background:#cbd5e1}.progress-segment.incomplete{background:#ef4444}.progress-segment:after{content:attr(data-tooltip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);background:#1e293b;color:#fff;padding:6px 10px;border-radius:6px;font-size:10px;white-space:pre-line;min-width:120px;max-width:180px;box-shadow:0 3px 10px #0003;z-index:1000;opacity:0;visibility:hidden;transition:opacity .15s ease;pointer-events:none}.progress-segment:hover:after{opacity:1;visibility:visible}.task-count{font-size:10px;font-weight:600;color:var(--text-secondary, #64748b);min-width:24px;text-align:right}.on-time-indicator{font-size:10px;color:#22c55e}.on-time-indicator.late{color:#ef4444}.statusunit{border-radius:30px;font-size:12px;text-transform:capitalize;font-weight:600;width:20px;height:20px;text-align:center;line-height:20px}.statusunit.Ton{background:#22c55e}.statusunit.Load{background:#3b82f6}.statusunit.Hourly{background:#f59e0b}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:50;border-radius:0 0 12px 12px}:host-context(.dark) .list-loader{background:#0f172a66}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: DriverListComponent, selector: "lib-driver-list", inputs: ["modalOpen", "driverListcollapse"], outputs: ["modalOpenChange"] }, { kind: "component", type: JobDetailsComponent, selector: "lib-job-details", inputs: ["modalOpen", "routeData"], outputs: ["modalOpenChange"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
341
342
  }
342
343
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: JobCodeComponent, decorators: [{
343
344
  type: Component,
344
- args: [{ selector: 'lib-job-code', standalone: true, imports: [LucideAngularModule, DriverListComponent, JobDetailsComponent, NgClass], template: "<div\n class=\"cards-list-container\"\n [class.floating]=\"listMode === 'floating'\"\n [class.sidebar]=\"listMode === 'sidebar'\"\n [class.inline]=\"listMode === 'inline'\"\n [class.collapsed]=\"collapsed\"\n>\n <div class=\"list-header\">\n <div class=\"header-title\">\n <span class=\"title-text\">Routes</span>\n <span class=\"routes-count\">({{ routes.length || 0 }})</span>\n </div>\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse()\"\n [title]=\"collapsed ? 'Expand' : 'Collapse'\"\n >\n @if (collapsed) {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n }\n </button>\n </div>\n @if (!collapsed) {\n <div class=\"cards-scroll-container\" #scrollContainer>\n @if (isLoading) {\n <div class=\"list-loader\">\n <lucide-icon [img]=\"icons.LoaderCircle\" [size]=\"32\" class=\"animate-spin text-amber-500\"></lucide-icon>\n </div>\n }\n @if(!isLoading && routes && routes.length){\n <div class=\"cards-list\">\n @for (route of routes; track $index) {\n <div class=\"card-wrapper\" (click)=\"toggleRouteSelection(route)\">\n <div\n class=\"route-card bg-white dark:bg-slate-800 border transition-all duration-200\"\n [class.border-brand-blue]=\"selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.border-gray-300]=\"!selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.dark:border-slate-700]=\"!selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.selected]=\"selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n >\n <div class=\"task-header justify-between\">\n <span class=\"job-code\">{{ route.order_number || 'N/A' }}</span>\n <div class=\"flex gap-2\">\n <div class=\"statusunit text-white\" [ngClass]=\"route.unit || ''\">{{ route.unit?.charAt(0) || 'U' }}</div>\n @if (config.repository !== 'customer') {\n <div\n class=\"statusunit bg-slate-900 dark:bg-white text-white dark:text-black flex items-center justify-center cursor-pointer hover:opacity-80\"\n (click)=\"showDriverModal = true; toggleCollapse(); $event.stopPropagation()\"\n >\n <lucide-icon [img]=\"icons.CarFront\" [size]=\"15\"></lucide-icon>\n </div>\n }\n <div\n class=\"text-black dark:text-white flex items-center justify-center cursor-pointer hover:opacity-80\"\n (click)=\"openDetail(route, true); $event.stopPropagation()\"\n (mouseenter)=\"openDetail(route, false)\"\n (mouseleave)=\"closeDetail(true)\"\n >\n <lucide-icon [img]=\"icons.Info\" [size]=\"20\"></lucide-icon>\n </div>\n </div>\n </div>\n <div class=\"customer-name font-semibold truncate\">{{ route.customer_name }}</div>\n <div class=\"material-info truncate text-gray-600 dark:text-gray-300\">{{ route.project || 'No Project' }}</div>\n <div class=\"location-flow mt-2 text-sm flex items-center gap-2\">\n <span class=\"pickup flex items-center gap-1 truncate max-w-[40%] text-green-600 dark:text-green-400\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n {{ (route.pickup_location || '').split('|')[0] || 'Unknown' }}\n </span>\n <span class=\"arrow text-gray-400\">\u2192</span>\n <span class=\"delivery truncate max-w-[40%] text-brand-blue\">{{ (route.delivery_location || '').split('|')[0] || 'Unknown' }}</span>\n </div>\n <div class=\"material-info mt-2 truncate font-medium\">{{ route.material || '' }}</div>\n <div class=\"driver-row-4 mt-3 flex items-center gap-2\">\n <div class=\"progress-bar flex-1 h-1.5 bg-gray-200 dark:bg-slate-700 rounded-full overflow-hidden flex\">\n <div class=\"progress-segment completed h-full bg-green-500 transition-all duration-300\" [style.width.%]=\"calculateStatusPercentage('done', route)\"></div>\n <div class=\"progress-segment ongoing h-full transition-all duration-300\" [style.backgroundColor]=\"'#fc0'\" [style.width.%]=\"calculateStatusPercentage('ongoing', route)\"></div>\n <div class=\"progress-segment open h-full bg-gray-300 dark:bg-slate-600 transition-all duration-300\" [style.width.%]=\"calculateStatusPercentage('open', route)\"></div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n } @else if(!isLoading && coolmapService.isDataFetched() && (!routes || routes.length === 0)) {\n <div class=\"empty-state\">\n <div class=\"text-gray-600 dark:text-gray-400 mt-2 text-center\">No Job code found.</div>\n </div>\n }\n </div>\n }\n</div>\n<lib-driver-list\n [(modalOpen)]=\"showDriverModal\"\n [driverListcollapse]=\"driverListcollapse()\"\n></lib-driver-list>\n<lib-job-details \n [modalOpen]=\"showDetailModal\" \n (modalOpenChange)=\"$event ? null : closeDetail(false)\" \n [routeData]=\"selectedJobDetail()\" \n [noBackdrop]=\"!isClickTriggered\"\n></lib-job-details>\n", styles: [":host{display:block}.cards-list-container{display:flex;flex-direction:column;height:100%;background:var(--bg-primary, white)}.cards-list-container.floating{position:absolute;top:12px;left:12px;width:280px;max-height:calc(100% - 24px);border-radius:12px;box-shadow:0 4px 24px #00000026;z-index:100;overflow:hidden}.cards-list-container.floating.collapsed{width:48px}.cards-list-container.sidebar{width:100%;border-right:1px solid var(--border-color, #e2e8f0)}.cards-list-container.inline{width:160px;min-width:160px;border-right:1px solid var(--border-color, #e2e8f0)}:host-context(.dark) .cards-list-container{background-color:#1e293b}:host-context(.dark) .cards-list-container.sidebar,:host-context(.dark) .cards-list-container.inline{border-color:#334155}.list-header{display:flex;align-items:center;justify-content:space-between;padding:12px;border-bottom:1px solid var(--border-color, #e2e8f0);background:var(--bg-secondary, #f8fafc)}:host-context(.dark) .list-header{background-color:#0f172a;border-color:#334155}.collapsed .list-header{padding:12px 8px;justify-content:center}.header-title{display:flex;align-items:center;gap:6px}.collapsed .header-title{display:none}.title-text{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .title-text{color:#f1f5f9}.routes-count{font-size:12px;color:var(--text-secondary, #64748b)}.collapse-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:transparent;color:var(--text-secondary, #64748b);cursor:pointer;border-radius:6px;transition:all .15s ease}.collapse-btn:hover{background:var(--hover-bg, #e2e8f0);color:var(--text-primary, #1e293b)}:host-context(.dark) .collapse-btn:hover{background-color:#334155;color:#f1f5f9}.cards-scroll-container{flex:1;overflow-y:auto;overflow-x:hidden}.cards-list{display:flex;flex-direction:column;gap:8px;padding:8px}.card-wrapper{border-radius:8px;transition:all .2s ease}.route-card{position:relative;padding:6px 10px;display:flex;flex-direction:column;gap:2px;border-radius:8px;cursor:pointer;transition:all .15s ease;min-height:72px}.route-card:hover{border-color:var(--accent-color, #3b82f6);box-shadow:0 2px 8px #00000014}.route-card.selected{border-color:var(--accent-color, #3b82f6);background:#3b82f60d}.task-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.job-code{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .job-code{color:#f1f5f9}.customer-name{font-size:12px;color:var(--text-secondary, #64748b);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.material-info{font-size:11px;color:var(--text-tertiary, #94a3b8);margin-bottom:6px;font-weight:500}.location-flow{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .arrow{color:var(--text-tertiary, #94a3b8)}.location-flow .delivery{color:#ef4444}.driver-row-4{display:flex;align-items:center;gap:4px;margin-top:2px}.progress-bar{display:flex;gap:2px}.progress-segment{height:6px;border-radius:2px;position:relative;cursor:pointer}.progress-segment.completed{background:#22c55e}.progress-segment.in_progress{background:#f59e0b}.progress-segment.pending{background:#cbd5e1}.progress-segment.incomplete{background:#ef4444}.progress-segment:after{content:attr(data-tooltip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);background:#1e293b;color:#fff;padding:6px 10px;border-radius:6px;font-size:10px;white-space:pre-line;min-width:120px;max-width:180px;box-shadow:0 3px 10px #0003;z-index:1000;opacity:0;visibility:hidden;transition:opacity .15s ease;pointer-events:none}.progress-segment:hover:after{opacity:1;visibility:visible}.task-count{font-size:10px;font-weight:600;color:var(--text-secondary, #64748b);min-width:24px;text-align:right}.on-time-indicator{font-size:10px;color:#22c55e}.on-time-indicator.late{color:#ef4444}.statusunit{border-radius:30px;font-size:12px;text-transform:capitalize;font-weight:600;width:20px;height:20px;text-align:center;line-height:20px}.statusunit.Ton{background:#22c55e}.statusunit.Load{background:#3b82f6}.statusunit.Hourly{background:#f59e0b}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:50;border-radius:0 0 12px 12px}:host-context(.dark) .list-loader{background:#0f172a66}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
345
+ args: [{ selector: 'lib-job-code', standalone: true, imports: [LucideAngularModule, DriverListComponent, JobDetailsComponent, NgClass], template: "<div\n class=\"cards-list-container\"\n [class.floating]=\"listMode === 'floating'\"\n [class.sidebar]=\"listMode === 'sidebar'\"\n [class.inline]=\"listMode === 'inline'\"\n [class.collapsed]=\"collapsed\"\n>\n <div class=\"list-header\">\n <div class=\"header-title\">\n <span class=\"title-text\">Routes</span>\n <span class=\"routes-count\">({{ routes.length || 0 }})</span>\n </div>\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse()\"\n [title]=\"collapsed ? 'Expand' : 'Collapse'\"\n >\n @if (collapsed) {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n }\n </button>\n </div>\n @if (!collapsed) {\n <div class=\"cards-scroll-container\" #scrollContainer>\n @if (listLoading) {\n <div class=\"list-loader\">\n <lucide-icon [img]=\"icons.LoaderCircle\" [size]=\"32\" class=\"animate-spin text-amber-500\"></lucide-icon>\n </div>\n }\n @if(!listLoading && routes && routes.length){\n <div class=\"cards-list\">\n @for (route of routes; track $index) {\n <div class=\"card-wrapper\" (click)=\"toggleRouteSelection(route)\">\n <div\n class=\"route-card bg-white dark:bg-slate-800 border transition-all duration-200\"\n [class.border-brand-blue]=\"selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.border-gray-300]=\"!selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.dark:border-slate-700]=\"!selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n [class.selected]=\"selectedRouteIds.includes(route.job_id || route.route_id || route.route_details_id || '')\"\n >\n <div class=\"task-header justify-between\">\n <span class=\"job-code\">{{ route.order_number || 'N/A' }}</span>\n <div class=\"flex gap-2\">\n <div class=\"statusunit text-white\" [ngClass]=\"route.unit || ''\">{{ route.unit?.charAt(0) || 'U' }}</div>\n @if (config.repository !== 'customer') {\n <div\n class=\"statusunit bg-slate-900 dark:bg-white text-white dark:text-black flex items-center justify-center cursor-pointer hover:opacity-80\"\n (click)=\"showDriverModal = true; toggleCollapse(); $event.stopPropagation()\"\n >\n <lucide-icon [img]=\"icons.CarFront\" [size]=\"15\"></lucide-icon>\n </div>\n }\n <div\n class=\"text-black dark:text-white flex items-center justify-center cursor-pointer hover:opacity-80\"\n (click)=\"openDetail(route, true); $event.stopPropagation()\"\n (mouseenter)=\"openDetail(route, false)\"\n (mouseleave)=\"closeDetail(true)\"\n >\n <lucide-icon [img]=\"icons.Info\" [size]=\"20\"></lucide-icon>\n </div>\n </div>\n </div>\n <div class=\"customer-name font-semibold truncate\">{{ route.customer_name }}</div>\n <div class=\"material-info truncate text-gray-600 dark:text-gray-300\">{{ route.project || 'No Project' }}</div>\n <div class=\"location-flow mt-2 text-sm flex items-center gap-2\">\n <span class=\"pickup flex items-center gap-1 truncate max-w-[40%] text-green-600 dark:text-green-400\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n {{ (route.pickup_location || '').split('|')[0] || 'Unknown' }}\n </span>\n <span class=\"arrow text-gray-400\">\u2192</span>\n <span class=\"delivery truncate max-w-[40%] text-brand-blue\">{{ (route.delivery_location || '').split('|')[0] || 'Unknown' }}</span>\n </div>\n <div class=\"material-info mt-2 truncate font-medium\">{{ route.material || '' }}</div>\n <div class=\"driver-row-4 mt-3 flex items-center gap-2\">\n <div class=\"progress-bar flex-1 h-1.5 bg-gray-200 dark:bg-slate-700 rounded-full overflow-hidden flex\">\n <div class=\"progress-segment completed h-full bg-green-500 transition-all duration-300\" [style.width.%]=\"calculateStatusPercentage('done', route)\"></div>\n <div class=\"progress-segment ongoing h-full transition-all duration-300\" [style.backgroundColor]=\"'#fc0'\" [style.width.%]=\"calculateStatusPercentage('ongoing', route)\"></div>\n <div class=\"progress-segment open h-full bg-gray-300 dark:bg-slate-600 transition-all duration-300\" [style.width.%]=\"calculateStatusPercentage('open', route)\"></div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n } @else if(!listLoading && coolmapService.isDataFetched() && (!routes || routes.length === 0)) {\n <div class=\"empty-state\">\n <div class=\"text-gray-600 dark:text-gray-400 mt-2 text-center\">No Job code found.</div>\n </div>\n }\n </div>\n }\n</div>\n<lib-driver-list\n [(modalOpen)]=\"showDriverModal\"\n [driverListcollapse]=\"driverListcollapse()\"\n></lib-driver-list>\n<lib-job-details \n [modalOpen]=\"showDetailModal\" \n (modalOpenChange)=\"$event ? null : closeDetail(false)\" \n [routeData]=\"selectedJobDetail()\" \n></lib-job-details>\n", styles: [":host{display:block}.cards-list-container{display:flex;flex-direction:column;height:100%;background:var(--bg-primary, white)}.cards-list-container.floating{position:absolute;top:12px;left:12px;width:280px;max-height:calc(100% - 24px);border-radius:12px;box-shadow:0 4px 24px #00000026;z-index:100;overflow:hidden}.cards-list-container.floating.collapsed{width:48px}.cards-list-container.sidebar{width:100%;border-right:1px solid var(--border-color, #e2e8f0)}.cards-list-container.inline{width:160px;min-width:160px;border-right:1px solid var(--border-color, #e2e8f0)}:host-context(.dark) .cards-list-container{background-color:#1e293b}:host-context(.dark) .cards-list-container.sidebar,:host-context(.dark) .cards-list-container.inline{border-color:#334155}.list-header{display:flex;align-items:center;justify-content:space-between;padding:12px;border-bottom:1px solid var(--border-color, #e2e8f0);background:var(--bg-secondary, #f8fafc)}:host-context(.dark) .list-header{background-color:#0f172a;border-color:#334155}.collapsed .list-header{padding:12px 8px;justify-content:center}.header-title{display:flex;align-items:center;gap:6px}.collapsed .header-title{display:none}.title-text{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .title-text{color:#f1f5f9}.routes-count{font-size:12px;color:var(--text-secondary, #64748b)}.collapse-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:transparent;color:var(--text-secondary, #64748b);cursor:pointer;border-radius:6px;transition:all .15s ease}.collapse-btn:hover{background:var(--hover-bg, #e2e8f0);color:var(--text-primary, #1e293b)}:host-context(.dark) .collapse-btn:hover{background-color:#334155;color:#f1f5f9}.cards-scroll-container{flex:1;overflow-y:auto;overflow-x:hidden}.cards-list{display:flex;flex-direction:column;gap:8px;padding:8px}.card-wrapper{border-radius:8px;transition:all .2s ease}.route-card{position:relative;padding:6px 10px;display:flex;flex-direction:column;gap:2px;border-radius:8px;cursor:pointer;transition:all .15s ease;min-height:72px}.route-card:hover{border-color:var(--accent-color, #3b82f6);box-shadow:0 2px 8px #00000014}.route-card.selected{border-color:var(--accent-color, #3b82f6);background:#3b82f60d}.task-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.job-code{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .job-code{color:#f1f5f9}.customer-name{font-size:12px;color:var(--text-secondary, #64748b);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.material-info{font-size:11px;color:var(--text-tertiary, #94a3b8);margin-bottom:6px;font-weight:500}.location-flow{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .arrow{color:var(--text-tertiary, #94a3b8)}.location-flow .delivery{color:#ef4444}.driver-row-4{display:flex;align-items:center;gap:4px;margin-top:2px}.progress-bar{display:flex;gap:2px}.progress-segment{height:6px;border-radius:2px;position:relative;cursor:pointer}.progress-segment.completed{background:#22c55e}.progress-segment.in_progress{background:#f59e0b}.progress-segment.pending{background:#cbd5e1}.progress-segment.incomplete{background:#ef4444}.progress-segment:after{content:attr(data-tooltip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);background:#1e293b;color:#fff;padding:6px 10px;border-radius:6px;font-size:10px;white-space:pre-line;min-width:120px;max-width:180px;box-shadow:0 3px 10px #0003;z-index:1000;opacity:0;visibility:hidden;transition:opacity .15s ease;pointer-events:none}.progress-segment:hover:after{opacity:1;visibility:visible}.task-count{font-size:10px;font-weight:600;color:var(--text-secondary, #64748b);min-width:24px;text-align:right}.on-time-indicator{font-size:10px;color:#22c55e}.on-time-indicator.late{color:#ef4444}.statusunit{border-radius:30px;font-size:12px;text-transform:capitalize;font-weight:600;width:20px;height:20px;text-align:center;line-height:20px}.statusunit.Ton{background:#22c55e}.statusunit.Load{background:#3b82f6}.statusunit.Hourly{background:#f59e0b}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:50;border-radius:0 0 12px 12px}:host-context(.dark) .list-loader{background:#0f172a66}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
345
346
  }], ctorParameters: () => [], propDecorators: { listMode: [{
346
347
  type: Input
347
348
  }], collapsible: [{
@@ -350,8 +351,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
350
351
  type: Input
351
352
  }], selectedRouteIds: [{
352
353
  type: Input
353
- }], isLoading: [{
354
- type: Input
355
354
  }], routeSelect: [{
356
355
  type: Output
357
356
  }], icons: [{
@@ -1838,33 +1837,40 @@ class CoolmapComponent {
1838
1837
  });
1839
1838
  // Effect 1: Manage Floating List (JobCode)
1840
1839
  effect(async () => {
1840
+ const routes = this.routesList();
1841
+ const selectedIds = this.selectedRouteIds();
1842
+ const isFetched = this.coolmapService.isDataFetched();
1843
+ const isLoading = this.coolmapService.isLoading();
1844
+ if (isLoading && !isFetched)
1845
+ return;
1841
1846
  if (this.activeSection() === 'Jobcode') {
1842
- const routes = this.routesList();
1843
- const selectedIds = this.selectedRouteIds();
1844
- // Queue the sync operation
1845
1847
  this.mapOpQueue = this.mapOpQueue.then(() => this.syncSpecificPrefix('jobcode', routes, selectedIds));
1846
1848
  }
1847
1849
  else {
1848
- // Clear jobcode prefix if not in the section
1849
1850
  this.mapOpQueue = this.mapOpQueue.then(() => this.syncSpecificPrefix('jobcode', [], []));
1850
1851
  }
1851
1852
  });
1852
1853
  // Effect 2: Manage Modal List (JobRouteList)
1853
1854
  effect(async () => {
1854
1855
  const modalRoutes = this.modalPlottedRoutes();
1855
- // Queue the sync operation
1856
+ const isFetched = this.coolmapService.isDataFetched();
1857
+ const isLoading = this.coolmapService.isLoading();
1858
+ if (isLoading && !isFetched)
1859
+ return;
1856
1860
  this.mapOpQueue = this.mapOpQueue.then(() => this.syncSpecificPrefix('jobrouteList', modalRoutes, modalRoutes.map(r => this.getRouteId(r))));
1857
1861
  });
1858
1862
  // Effect 3: Manage View Route Section
1859
1863
  effect(async () => {
1864
+ const routes = this.viewRoutesList();
1865
+ const selectedIds = this.selectedRouteIds();
1866
+ const isFetched = this.coolmapService.isDataFetched();
1867
+ const isLoading = this.coolmapService.isLoading();
1868
+ if (isLoading && !isFetched)
1869
+ return;
1860
1870
  if (this.activeSection() === 'ViewRoute') {
1861
- const routes = this.viewRoutesList();
1862
- const selectedIds = this.selectedRouteIds();
1863
- // Queue the sync operation
1864
1871
  this.mapOpQueue = this.mapOpQueue.then(() => this.syncSpecificPrefix('viewroute', routes, selectedIds));
1865
1872
  }
1866
1873
  else {
1867
- // Clear viewroute prefix if not in the section
1868
1874
  this.mapOpQueue = this.mapOpQueue.then(() => this.syncSpecificPrefix('viewroute', [], []));
1869
1875
  }
1870
1876
  });
@@ -1875,7 +1881,6 @@ class CoolmapComponent {
1875
1881
  }
1876
1882
  }
1877
1883
  ngOnInit() {
1878
- this.coolmapService.isLoading.set(true);
1879
1884
  this.loadData(this.dateValue());
1880
1885
  }
1881
1886
  getUnitList() {
@@ -1894,6 +1899,7 @@ class CoolmapComponent {
1894
1899
  }
1895
1900
  ngOnChanges(changes) {
1896
1901
  if (changes['customerRepoDetails'] && !changes['customerRepoDetails'].firstChange) {
1902
+ this.coolmapService.isLoading.set(true);
1897
1903
  if (this.config.repository === 'customer') {
1898
1904
  if (this.activeSection() === 'Jobcode') {
1899
1905
  this.loadData(this.dateValue());
@@ -1969,12 +1975,13 @@ class CoolmapComponent {
1969
1975
  return ele;
1970
1976
  });
1971
1977
  this.routesList.set(list);
1978
+ this.coolmapService.isDataFetched.set(true);
1972
1979
  }
1973
1980
  else {
1974
1981
  this.routesList.set([]);
1982
+ this.coolmapService.isLoading.set(false);
1983
+ this.coolmapService.isDataFetched.set(true);
1975
1984
  }
1976
- this.coolmapService.isLoading.set(false);
1977
- this.coolmapService.isDataFetched.set(true);
1978
1985
  },
1979
1986
  error: () => {
1980
1987
  this.routesList.set([]);
@@ -2041,12 +2048,13 @@ class CoolmapComponent {
2041
2048
  return ele;
2042
2049
  });
2043
2050
  this.viewRoutesList.set(list);
2051
+ this.coolmapService.isDataFetched.set(true);
2044
2052
  }
2045
2053
  else {
2046
2054
  this.viewRoutesList.set([]);
2055
+ this.coolmapService.isLoading.set(false);
2056
+ this.coolmapService.isDataFetched.set(true);
2047
2057
  }
2048
- this.coolmapService.isLoading.set(false);
2049
- this.coolmapService.isDataFetched.set(true);
2050
2058
  }
2051
2059
  getUnitName(data) {
2052
2060
  let unitName = '';
@@ -2067,6 +2075,7 @@ class CoolmapComponent {
2067
2075
  return materialName || data.material || '';
2068
2076
  }
2069
2077
  onDateChange(event) {
2078
+ this.coolmapService.isLoading.set(true);
2070
2079
  const target = event.target;
2071
2080
  if (target && target.value) {
2072
2081
  this.coolmapService.resetModals.update(v => v + 1);
@@ -2123,7 +2132,6 @@ class CoolmapComponent {
2123
2132
  }
2124
2133
  // 5. Perform additions for THIS prefix
2125
2134
  if (toAdd.length > 0) {
2126
- this.coolmapService.isLoading.set(true);
2127
2135
  for (const regId of toAdd) {
2128
2136
  const id = regId.substring(prefix.length + 1);
2129
2137
  const routeObj = sourceRoutes.find(r => this.getRouteId(r) === id);
@@ -2151,7 +2159,9 @@ class CoolmapComponent {
2151
2159
  const compositeVisible = selectedIds.map(id => `${prefix}-${id}`);
2152
2160
  const showAllForThisPrefix = (['jobcode', 'viewroute'].includes(prefix) && selectedIds.length === 0);
2153
2161
  this.mapService.setRoutesVisibility(compositeVisible, showAllForThisPrefix, prefix);
2154
- this.coolmapService.isLoading.set(false);
2162
+ if (this.coolmapService.isDataFetched()) {
2163
+ this.coolmapService.isLoading.set(false);
2164
+ }
2155
2165
  }
2156
2166
  toggleSelection(id) {
2157
2167
  this.selectedRouteIds.update(ids => {
@@ -2264,7 +2274,7 @@ class CoolmapComponent {
2264
2274
  this.showShareModal.set(true);
2265
2275
  }
2266
2276
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CoolmapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2267
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: CoolmapComponent, isStandalone: true, selector: "lib-coolmap", inputs: { mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: false, isRequired: false, transformFunction: null }, activeSection: { classPropertyName: "activeSection", publicName: "activeSection", isSignal: true, isRequired: false, transformFunction: null }, customerRepoDetails: { classPropertyName: "customerRepoDetails", publicName: "customerRepoDetails", isSignal: false, isRequired: false, transformFunction: null }, userDetails: { classPropertyName: "userDetails", publicName: "userDetails", isSignal: false, isRequired: false, transformFunction: null }, darkMode: { classPropertyName: "darkMode", publicName: "darkMode", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onClick($event)" } }, viewQueries: [{ propertyName: "mapContainer", first: true, predicate: ["mapContainer"], descendants: true }, { propertyName: "searchContainer", first: true, predicate: ["searchContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"center-area\">\n <div [formGroup]=\"filterForm\" class=\"toolbar flex flex-col sm:flex-row md:h-[55px] h-auto py-2 px-2 gap-3 items-center\">\n <div class=\"toolbar-left flex items-center gap-3 flex-1\">\n @if (activeSection() === 'Jobcode') {\n <div class=\"relative w-full sm:w-auto group mt-[25px]\">\n <input\n type=\"text\"\n [value]=\"displayDate()\"\n readonly\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"dateInput.showPicker()\"\n class=\"w-full pl-3 pr-10 py-2 rounded-lg border border-gray-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-blue focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer\"\n />\n <lucide-icon \n [img]=\"icons.Calendar\" \n [size]=\"18\" \n (click)=\"!coolmapService.isLoading() && dateInput.showPicker()\"\n [class.pointer-events-none]=\"coolmapService.isLoading()\"\n [class.opacity-50]=\"coolmapService.isLoading()\"\n class=\"absolute right-[6px] top-[5px] text-white-400 group-hover:text-brand-blue transition-colors cursor-pointer\"\n ></lucide-icon>\n <input\n #dateInput\n type=\"date\"\n [value]=\"dateValue()\"\n (change)=\"onDateChange($event)\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"absolute inset-0 w-0 h-0 opacity-0 pointer-events-none\"\n />\n </div>\n <span class=\"toolbar-divider hidden sm:flex h-6 w-[1px] bg-gray-200 dark:bg-slate-700\"></span>\n }\n @if (filters() && filters().length > 0) {\n <div class=\"flex flex-wrap gap-2 ml-2\">\n @for (filter of filters(); track filter.value + filter.type) {\n <div class=\"inline-flex items-center gap-1 px-2 py-2.5 rounded-xl bg-slate-200 dark:bg-slate-700 text-gray-800 dark:text-gray-200 text-xs font-medium border border-gray-300 dark:border-slate-600\">\n <span class=\"capitalize opacity-80\">{{ filter.type }}:</span> {{ filter.name }}\n <button type=\"button\" (click)=\"removeFilter(filter)\" class=\"hover:opacity-75 transition-opacity ml-1\">\n <lucide-icon [img]=\"icons.X\" [size]=\"12\"></lucide-icon>\n </button>\n </div>\n }\n </div>\n }\n <div #searchContainer class=\"relative items-center flex-1\">\n <lucide-icon [img]=\"icons.Search\" [size]=\"18\" class=\"absolute left-[0.55rem] top-[50%] -translate-y-1/2 text-gray-400\"></lucide-icon>\n <input\n type=\"text\"\n formControlName=\"search\"\n [attr.disabled]=\"coolmapService.isLoading() ? true : null\"\n placeholder=\"Search routes...\"\n class=\"w-full pl-10 pr-10 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-amber-500 focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n (focus)=\"onSearchFocus()\"\n />\n\n @if (filterForm.value.search) {\n <button (click)=\"filterForm.controls.search.setValue('')\" class=\"absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\">\n <lucide-icon [img]=\"icons.X\" [size]=\"16\"></lucide-icon>\n </button>\n }\n\n <!-- Autocomplete Dropdown -->\n @if (dropdownOpen() && filteredOptions().length > 0) {\n <div class=\"absolute z-70 left-0 right-0 top-full mt-1 max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n @for (option of filteredOptions(); track option.value + option.type) {\n <div (click)=\"selectFilter(option)\" class=\"px-4 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 cursor-pointer text-xs font-normal border-b border-gray-100 dark:border-slate-700 last:border-0 dark:text-white\">\n <span class=\"capitalize\">{{ option.type }}:</span>\n {{ option.label }}\n </div>\n }\n </div>\n } @else if (!coolmapService.isLoading() && (!filteredOptions() || filteredOptions().length === 0) && filterForm.value.search) {\n <div class=\"absolute z-70 left-0 right-0 top-full mt-1 p-4 text-center text-gray-400 text-sm bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n No results found.\n </div>\n }\n\n \n </div>\n </div>\n <div class=\"toolbar-right\">\n @if (selectedRouteIds().length > 0) {\n <button\n type=\"button\"\n (click)=\"clearSelection()\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n >\n Show all routes ({{ selectedRouteIds().length }})\n </button>\n }\n @if (activeSection() === 'ViewRoute') {\n <button\n type=\"button\"\n class=\"inline-flex items-center justify-center gap-2 px-4 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"openAddRouteModal()\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Add Route\n </button>\n }\n\n @if(activeSection() === 'Jobcode'){\n <button\n class=\"inline-flex items-center gap-2 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed relative group\"\n (click)=\"showRouteList = true\"\n [disabled]=\"coolmapService.isLoading()\">\n <lucide-icon [img]=\"icons.Route\" [size]=\"20\"></lucide-icon>\n <div\n class=\"absolute top-full right-0 mt-2 group-hover:block hidden bg-gray-800 dark:bg-white text-white dark:text-black text-[10px] rounded py-1 px-2 whitespace-nowrap\">\n Show Route List\n <div\n class=\"absolute -top-[8px] left-[60px] border-4 border-transparent border-b-gray-800 dark:border-b-white\">\n </div>\n </div>\n </button>}\n </div>\n </div>\n <div class=\"view-content\">\n <div class=\"full-view\">\n <div class=\"map-container\">\n <div class=\"mapbox-container\" #mapContainer></div>\n </div>\n </div>\n\n <!-- FOR JOBCODE -->\n @if (activeSection() === 'Jobcode') {\n <lib-job-code \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\">\n </lib-job-code>\n }\n\n <!-- FOR VIEWROUTE -->\n @if (activeSection() === 'ViewRoute') {\n <lib-view-route-list \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\"\n (editRoute)=\"openEditModal($event)\"\n ></lib-view-route-list>\n }\n </div>\n @if (config.repository === 'coolmap') {\n <div class=\"status-bar\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ masterStats().Done }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ masterStats().Incomplete }}</span>\n <span class=\"stat-label\">Incomplete</span>\n </div>\n\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ masterStats().Ongoing }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ masterStats().Open }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n </div>\n }\n</div>\n<lib-job-route-list \n [initialRoutes]=\"viewRoutesList()\"\n [(modalOpen)]=\"showRouteList\"\n [selectedRouteIds]=\"modalPlottedIds()\"\n (routeSelect)=\"toggleModalRoute($event)\"\n (masterToggleEvent)=\"modalMasterToggle($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n (shareRoute)=\"handleShareRoute($event)\"\n></lib-job-route-list>\n<lib-add-route \n [modalOpen]=\"addRouteModal\"\n (modalOpenChange)=\"onAddRouteModalChange($event)\"\n (routeSaved)=\"onRouteSaved($event)\"\n (routeDeleted)=\"onRouteDeleted($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n [routeData]=\"selectedRouteForEdit()\"\n></lib-add-route>\n\n@if (showShareModal()) {\n <lib-share-route\n [openShareRouteDetails]=\"shareRouteData()\"\n [userDetails]=\"userDetails\"\n (closePopupEmit)=\"showShareModal.set(false)\" class=\"relative\"\n ></lib-share-route>\n}\n\n<ag-toast-container></ag-toast-container>\n", styles: [":host{display:block;width:100%;height:100%;min-height:400px}.center-area{height:100%;display:flex;flex-direction:column;overflow:hidden}.view-content{flex:1;position:relative;overflow:hidden;z-index:10}.full-view{position:absolute;inset:0}.map-container,.mapbox-container{width:100%;height:100%}.toolbar{align-items:center;justify-content:space-between;background:var(--bg-primary, white);border-bottom:1px solid var(--border-color, #e2e8f0);flex-shrink:0;gap:8px;position:relative;z-index:12}:host-context(.dark) .toolbar{background:var(--bg-dark-primary, #1e293b);border-color:var(--border-dark, #334155);box-shadow:0 1px 3px #0000004d}.toolbar-left{display:flex;align-items:center;gap:12px;flex-shrink:0}.toolbar-divider{width:1px;height:20px;background:var(--border-color, #e2e8f0);margin:0 2px;flex-shrink:0}:host-context(.dark) .toolbar-divider{background:#475569}.toolbar-right{display:flex;align-items:center;gap:10px;flex-shrink:0}.status-bar{display:flex;align-items:center;height:100%;padding:0 16px;background:var(--status-bar-bg, #1e293b);color:#fff;font-size:12px;gap:20px;flex-shrink:0;height:36px}.stats-row{display:flex;align-items:center;gap:20px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.route-list-wrapper{position:absolute;top:10px;left:10px;bottom:10px;width:380px;z-index:20;pointer-events:none;display:flex;flex-direction:column}@media (max-width: 1024px){.route-list-wrapper{width:320px}}.route-list-wrapper>*{pointer-events:auto}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;border-radius:12px;border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #1f268712}:host-context(.dark) .list-loader{background:#0f172a66;border-color:#ffffff1a}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: JobCodeComponent, selector: "lib-job-code", inputs: ["listMode", "collapsible", "routes", "selectedRouteIds", "isLoading"], outputs: ["routeSelect"] }, { kind: "component", type: ViewRouteListComponent, selector: "lib-view-route-list", inputs: ["listMode", "collapsible", "routes", "selectedRouteIds", "isLoading"], outputs: ["routeSelect", "editRoute"] }, { kind: "component", type: JobRouteListComponent, selector: "lib-job-route-list", inputs: ["customerRepoDetails", "selectedRouteIds", "modalOpen", "initialRoutes"], outputs: ["modalOpenChange", "routeSelect", "masterToggleEvent", "shareRoute"] }, { kind: "component", type: AddRouteComponent, selector: "lib-add-route", inputs: ["modalOpen", "routeData", "customerRepoDetails"], outputs: ["modalOpenChange", "routeDeleted", "routeSaved"] }, { kind: "component", type: ShareRouteComponent, selector: "lib-share-route", inputs: ["openShareRouteDetails", "userDetails"], outputs: ["closePopupEmit"] }, { kind: "component", type: AgToastContainerComponent, selector: "ag-toast-container" }] });
2277
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: CoolmapComponent, isStandalone: true, selector: "lib-coolmap", inputs: { mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: false, isRequired: false, transformFunction: null }, activeSection: { classPropertyName: "activeSection", publicName: "activeSection", isSignal: true, isRequired: false, transformFunction: null }, customerRepoDetails: { classPropertyName: "customerRepoDetails", publicName: "customerRepoDetails", isSignal: false, isRequired: false, transformFunction: null }, userDetails: { classPropertyName: "userDetails", publicName: "userDetails", isSignal: false, isRequired: false, transformFunction: null }, darkMode: { classPropertyName: "darkMode", publicName: "darkMode", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onClick($event)" } }, viewQueries: [{ propertyName: "mapContainer", first: true, predicate: ["mapContainer"], descendants: true }, { propertyName: "searchContainer", first: true, predicate: ["searchContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"center-area\">\n <div [formGroup]=\"filterForm\" class=\"toolbar flex flex-col sm:flex-row md:h-[55px] h-auto py-2 px-2 gap-3 items-center\">\n <div class=\"toolbar-left flex items-center gap-3 flex-1\">\n @if (activeSection() === 'Jobcode') {\n <div class=\"relative w-full sm:w-auto group mt-[25px]\">\n <input\n type=\"text\"\n [value]=\"displayDate()\"\n readonly\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"dateInput.showPicker()\"\n class=\"w-full pl-3 pr-10 py-2 rounded-lg border border-gray-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-blue focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer\"\n />\n <lucide-icon \n [img]=\"icons.Calendar\" \n [size]=\"18\" \n (click)=\"!coolmapService.isLoading() && dateInput.showPicker()\"\n [class.pointer-events-none]=\"coolmapService.isLoading()\"\n [class.opacity-50]=\"coolmapService.isLoading()\"\n class=\"absolute right-[6px] top-[5px] text-white-400 group-hover:text-brand-blue transition-colors cursor-pointer\"\n ></lucide-icon>\n <input\n #dateInput\n type=\"date\"\n [value]=\"dateValue()\"\n (change)=\"onDateChange($event)\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"absolute inset-0 w-0 h-0 opacity-0 pointer-events-none\"\n />\n </div>\n <span class=\"toolbar-divider hidden sm:flex h-6 w-[1px] bg-gray-200 dark:bg-slate-700\"></span>\n }\n @if (filters() && filters().length > 0) {\n <div class=\"flex flex-wrap gap-2 ml-2\">\n @for (filter of filters(); track filter.value + filter.type) {\n <div class=\"inline-flex items-center gap-1 px-2 py-2.5 rounded-xl bg-slate-200 dark:bg-slate-700 text-gray-800 dark:text-gray-200 text-xs font-medium border border-gray-300 dark:border-slate-600\">\n <span class=\"capitalize opacity-80\">{{ filter.type }}:</span> {{ filter.name }}\n <button type=\"button\" (click)=\"removeFilter(filter)\" class=\"hover:opacity-75 transition-opacity ml-1\">\n <lucide-icon [img]=\"icons.X\" [size]=\"12\"></lucide-icon>\n </button>\n </div>\n }\n </div>\n }\n <div #searchContainer class=\"relative items-center flex-1\">\n <lucide-icon [img]=\"icons.Search\" [size]=\"18\" class=\"absolute left-[0.55rem] top-[50%] -translate-y-1/2 text-gray-400\"></lucide-icon>\n <input\n type=\"text\"\n formControlName=\"search\"\n [attr.disabled]=\"coolmapService.isLoading() ? true : null\"\n placeholder=\"Search routes...\"\n class=\"w-full pl-10 pr-10 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-amber-500 focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n (focus)=\"onSearchFocus()\"\n />\n\n @if (filterForm.value.search) {\n <button (click)=\"filterForm.controls.search.setValue('')\" class=\"absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\">\n <lucide-icon [img]=\"icons.X\" [size]=\"16\"></lucide-icon>\n </button>\n }\n\n <!-- Autocomplete Dropdown -->\n @if (dropdownOpen() && filteredOptions().length > 0) {\n <div class=\"absolute z-70 left-0 right-0 top-full mt-1 max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n @for (option of filteredOptions(); track option.value + option.type) {\n <div (click)=\"selectFilter(option)\" class=\"px-4 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 cursor-pointer text-xs font-normal border-b border-gray-100 dark:border-slate-700 last:border-0 dark:text-white\">\n <span class=\"capitalize\">{{ option.type }}:</span>\n {{ option.label }}\n </div>\n }\n </div>\n } @else if (!coolmapService.isLoading() && (!filteredOptions() || filteredOptions().length === 0) && filterForm.value.search) {\n <div class=\"absolute z-70 left-0 right-0 top-full mt-1 p-4 text-center text-gray-400 text-sm bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n No results found.\n </div>\n }\n\n \n </div>\n </div>\n <div class=\"toolbar-right\">\n @if (selectedRouteIds().length > 0) {\n <button\n type=\"button\"\n (click)=\"clearSelection()\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n >\n Show all routes ({{ selectedRouteIds().length }})\n </button>\n }\n @if (activeSection() === 'ViewRoute') {\n <button\n type=\"button\"\n class=\"inline-flex items-center justify-center gap-2 px-4 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"openAddRouteModal()\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Add Route\n </button>\n }\n\n @if(activeSection() === 'Jobcode'){\n <button\n class=\"inline-flex items-center gap-2 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed relative group\"\n (click)=\"showRouteList = true\"\n [disabled]=\"coolmapService.isLoading()\">\n <lucide-icon [img]=\"icons.Route\" [size]=\"20\"></lucide-icon>\n <div\n class=\"absolute top-full right-0 mt-2 group-hover:block hidden bg-gray-800 dark:bg-white text-white dark:text-black text-[10px] rounded py-1 px-2 whitespace-nowrap\">\n Show Route List\n <div\n class=\"absolute -top-[8px] left-[60px] border-4 border-transparent border-b-gray-800 dark:border-b-white\">\n </div>\n </div>\n </button>}\n </div>\n </div>\n <div class=\"view-content\">\n <div class=\"full-view\">\n <div class=\"map-container\">\n <div class=\"mapbox-container\" #mapContainer></div>\n </div>\n </div>\n <!-- FOR JOBCODE -->\n @if (activeSection() === 'Jobcode') {\n <lib-job-code \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n (routeSelect)=\"toggleSelection($event)\">\n </lib-job-code>\n }\n\n <!-- FOR VIEWROUTE -->\n @if (activeSection() === 'ViewRoute') {\n <lib-view-route-list \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\"\n (editRoute)=\"openEditModal($event)\"\n ></lib-view-route-list>\n }\n </div>\n @if (config.repository === 'coolmap') {\n <div class=\"status-bar\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ masterStats().Done }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ masterStats().Incomplete }}</span>\n <span class=\"stat-label\">Incomplete</span>\n </div>\n\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ masterStats().Ongoing }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ masterStats().Open }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n </div>\n }\n</div>\n<lib-job-route-list \n [initialRoutes]=\"viewRoutesList()\"\n [(modalOpen)]=\"showRouteList\"\n [selectedRouteIds]=\"modalPlottedIds()\"\n (routeSelect)=\"toggleModalRoute($event)\"\n (masterToggleEvent)=\"modalMasterToggle($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n (shareRoute)=\"handleShareRoute($event)\"\n></lib-job-route-list>\n<lib-add-route \n [modalOpen]=\"addRouteModal\"\n (modalOpenChange)=\"onAddRouteModalChange($event)\"\n (routeSaved)=\"onRouteSaved($event)\"\n (routeDeleted)=\"onRouteDeleted($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n [routeData]=\"selectedRouteForEdit()\"\n></lib-add-route>\n\n@if (showShareModal()) {\n <lib-share-route\n [openShareRouteDetails]=\"shareRouteData()\"\n [userDetails]=\"userDetails\"\n (closePopupEmit)=\"showShareModal.set(false)\" class=\"relative\"\n ></lib-share-route>\n}\n\n<ag-toast-container></ag-toast-container>\n", styles: [":host{display:block;width:100%;height:100%;min-height:400px}.center-area{height:100%;display:flex;flex-direction:column;overflow:hidden}.view-content{flex:1;position:relative;overflow:hidden;z-index:10}.full-view{position:absolute;inset:0}.map-container,.mapbox-container{width:100%;height:100%}.toolbar{align-items:center;justify-content:space-between;background:var(--bg-primary, white);border-bottom:1px solid var(--border-color, #e2e8f0);flex-shrink:0;gap:8px;position:relative;z-index:12}:host-context(.dark) .toolbar{background:var(--bg-dark-primary, #1e293b);border-color:var(--border-dark, #334155);box-shadow:0 1px 3px #0000004d}.toolbar-left{display:flex;align-items:center;gap:12px;flex-shrink:0}.toolbar-divider{width:1px;height:20px;background:var(--border-color, #e2e8f0);margin:0 2px;flex-shrink:0}:host-context(.dark) .toolbar-divider{background:#475569}.toolbar-right{display:flex;align-items:center;gap:10px;flex-shrink:0}.status-bar{display:flex;align-items:center;height:100%;padding:0 16px;background:var(--status-bar-bg, #1e293b);color:#fff;font-size:12px;gap:20px;flex-shrink:0;height:36px}.stats-row{display:flex;align-items:center;gap:20px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.route-list-wrapper{position:absolute;top:10px;left:10px;bottom:10px;width:380px;z-index:20;pointer-events:none;display:flex;flex-direction:column}@media (max-width: 1024px){.route-list-wrapper{width:320px}}.route-list-wrapper>*{pointer-events:auto}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;border-radius:12px;border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #1f268712}:host-context(.dark) .list-loader{background:#0f172a66;border-color:#ffffff1a}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: JobCodeComponent, selector: "lib-job-code", inputs: ["listMode", "collapsible", "routes", "selectedRouteIds"], outputs: ["routeSelect"] }, { kind: "component", type: ViewRouteListComponent, selector: "lib-view-route-list", inputs: ["listMode", "collapsible", "routes", "selectedRouteIds", "isLoading"], outputs: ["routeSelect", "editRoute"] }, { kind: "component", type: JobRouteListComponent, selector: "lib-job-route-list", inputs: ["customerRepoDetails", "selectedRouteIds", "modalOpen", "initialRoutes"], outputs: ["modalOpenChange", "routeSelect", "masterToggleEvent", "shareRoute"] }, { kind: "component", type: AddRouteComponent, selector: "lib-add-route", inputs: ["modalOpen", "routeData", "customerRepoDetails"], outputs: ["modalOpenChange", "routeDeleted", "routeSaved"] }, { kind: "component", type: ShareRouteComponent, selector: "lib-share-route", inputs: ["openShareRouteDetails", "userDetails"], outputs: ["closePopupEmit"] }, { kind: "component", type: AgToastContainerComponent, selector: "ag-toast-container" }] });
2268
2278
  }
2269
2279
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CoolmapComponent, decorators: [{
2270
2280
  type: Component,
@@ -2278,7 +2288,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
2278
2288
  AddRouteComponent,
2279
2289
  ShareRouteComponent,
2280
2290
  AgToastContainerComponent,
2281
- ], template: "<div class=\"center-area\">\n <div [formGroup]=\"filterForm\" class=\"toolbar flex flex-col sm:flex-row md:h-[55px] h-auto py-2 px-2 gap-3 items-center\">\n <div class=\"toolbar-left flex items-center gap-3 flex-1\">\n @if (activeSection() === 'Jobcode') {\n <div class=\"relative w-full sm:w-auto group mt-[25px]\">\n <input\n type=\"text\"\n [value]=\"displayDate()\"\n readonly\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"dateInput.showPicker()\"\n class=\"w-full pl-3 pr-10 py-2 rounded-lg border border-gray-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-blue focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer\"\n />\n <lucide-icon \n [img]=\"icons.Calendar\" \n [size]=\"18\" \n (click)=\"!coolmapService.isLoading() && dateInput.showPicker()\"\n [class.pointer-events-none]=\"coolmapService.isLoading()\"\n [class.opacity-50]=\"coolmapService.isLoading()\"\n class=\"absolute right-[6px] top-[5px] text-white-400 group-hover:text-brand-blue transition-colors cursor-pointer\"\n ></lucide-icon>\n <input\n #dateInput\n type=\"date\"\n [value]=\"dateValue()\"\n (change)=\"onDateChange($event)\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"absolute inset-0 w-0 h-0 opacity-0 pointer-events-none\"\n />\n </div>\n <span class=\"toolbar-divider hidden sm:flex h-6 w-[1px] bg-gray-200 dark:bg-slate-700\"></span>\n }\n @if (filters() && filters().length > 0) {\n <div class=\"flex flex-wrap gap-2 ml-2\">\n @for (filter of filters(); track filter.value + filter.type) {\n <div class=\"inline-flex items-center gap-1 px-2 py-2.5 rounded-xl bg-slate-200 dark:bg-slate-700 text-gray-800 dark:text-gray-200 text-xs font-medium border border-gray-300 dark:border-slate-600\">\n <span class=\"capitalize opacity-80\">{{ filter.type }}:</span> {{ filter.name }}\n <button type=\"button\" (click)=\"removeFilter(filter)\" class=\"hover:opacity-75 transition-opacity ml-1\">\n <lucide-icon [img]=\"icons.X\" [size]=\"12\"></lucide-icon>\n </button>\n </div>\n }\n </div>\n }\n <div #searchContainer class=\"relative items-center flex-1\">\n <lucide-icon [img]=\"icons.Search\" [size]=\"18\" class=\"absolute left-[0.55rem] top-[50%] -translate-y-1/2 text-gray-400\"></lucide-icon>\n <input\n type=\"text\"\n formControlName=\"search\"\n [attr.disabled]=\"coolmapService.isLoading() ? true : null\"\n placeholder=\"Search routes...\"\n class=\"w-full pl-10 pr-10 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-amber-500 focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n (focus)=\"onSearchFocus()\"\n />\n\n @if (filterForm.value.search) {\n <button (click)=\"filterForm.controls.search.setValue('')\" class=\"absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\">\n <lucide-icon [img]=\"icons.X\" [size]=\"16\"></lucide-icon>\n </button>\n }\n\n <!-- Autocomplete Dropdown -->\n @if (dropdownOpen() && filteredOptions().length > 0) {\n <div class=\"absolute z-70 left-0 right-0 top-full mt-1 max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n @for (option of filteredOptions(); track option.value + option.type) {\n <div (click)=\"selectFilter(option)\" class=\"px-4 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 cursor-pointer text-xs font-normal border-b border-gray-100 dark:border-slate-700 last:border-0 dark:text-white\">\n <span class=\"capitalize\">{{ option.type }}:</span>\n {{ option.label }}\n </div>\n }\n </div>\n } @else if (!coolmapService.isLoading() && (!filteredOptions() || filteredOptions().length === 0) && filterForm.value.search) {\n <div class=\"absolute z-70 left-0 right-0 top-full mt-1 p-4 text-center text-gray-400 text-sm bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n No results found.\n </div>\n }\n\n \n </div>\n </div>\n <div class=\"toolbar-right\">\n @if (selectedRouteIds().length > 0) {\n <button\n type=\"button\"\n (click)=\"clearSelection()\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n >\n Show all routes ({{ selectedRouteIds().length }})\n </button>\n }\n @if (activeSection() === 'ViewRoute') {\n <button\n type=\"button\"\n class=\"inline-flex items-center justify-center gap-2 px-4 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"openAddRouteModal()\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Add Route\n </button>\n }\n\n @if(activeSection() === 'Jobcode'){\n <button\n class=\"inline-flex items-center gap-2 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed relative group\"\n (click)=\"showRouteList = true\"\n [disabled]=\"coolmapService.isLoading()\">\n <lucide-icon [img]=\"icons.Route\" [size]=\"20\"></lucide-icon>\n <div\n class=\"absolute top-full right-0 mt-2 group-hover:block hidden bg-gray-800 dark:bg-white text-white dark:text-black text-[10px] rounded py-1 px-2 whitespace-nowrap\">\n Show Route List\n <div\n class=\"absolute -top-[8px] left-[60px] border-4 border-transparent border-b-gray-800 dark:border-b-white\">\n </div>\n </div>\n </button>}\n </div>\n </div>\n <div class=\"view-content\">\n <div class=\"full-view\">\n <div class=\"map-container\">\n <div class=\"mapbox-container\" #mapContainer></div>\n </div>\n </div>\n\n <!-- FOR JOBCODE -->\n @if (activeSection() === 'Jobcode') {\n <lib-job-code \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\">\n </lib-job-code>\n }\n\n <!-- FOR VIEWROUTE -->\n @if (activeSection() === 'ViewRoute') {\n <lib-view-route-list \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\"\n (editRoute)=\"openEditModal($event)\"\n ></lib-view-route-list>\n }\n </div>\n @if (config.repository === 'coolmap') {\n <div class=\"status-bar\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ masterStats().Done }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ masterStats().Incomplete }}</span>\n <span class=\"stat-label\">Incomplete</span>\n </div>\n\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ masterStats().Ongoing }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ masterStats().Open }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n </div>\n }\n</div>\n<lib-job-route-list \n [initialRoutes]=\"viewRoutesList()\"\n [(modalOpen)]=\"showRouteList\"\n [selectedRouteIds]=\"modalPlottedIds()\"\n (routeSelect)=\"toggleModalRoute($event)\"\n (masterToggleEvent)=\"modalMasterToggle($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n (shareRoute)=\"handleShareRoute($event)\"\n></lib-job-route-list>\n<lib-add-route \n [modalOpen]=\"addRouteModal\"\n (modalOpenChange)=\"onAddRouteModalChange($event)\"\n (routeSaved)=\"onRouteSaved($event)\"\n (routeDeleted)=\"onRouteDeleted($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n [routeData]=\"selectedRouteForEdit()\"\n></lib-add-route>\n\n@if (showShareModal()) {\n <lib-share-route\n [openShareRouteDetails]=\"shareRouteData()\"\n [userDetails]=\"userDetails\"\n (closePopupEmit)=\"showShareModal.set(false)\" class=\"relative\"\n ></lib-share-route>\n}\n\n<ag-toast-container></ag-toast-container>\n", styles: [":host{display:block;width:100%;height:100%;min-height:400px}.center-area{height:100%;display:flex;flex-direction:column;overflow:hidden}.view-content{flex:1;position:relative;overflow:hidden;z-index:10}.full-view{position:absolute;inset:0}.map-container,.mapbox-container{width:100%;height:100%}.toolbar{align-items:center;justify-content:space-between;background:var(--bg-primary, white);border-bottom:1px solid var(--border-color, #e2e8f0);flex-shrink:0;gap:8px;position:relative;z-index:12}:host-context(.dark) .toolbar{background:var(--bg-dark-primary, #1e293b);border-color:var(--border-dark, #334155);box-shadow:0 1px 3px #0000004d}.toolbar-left{display:flex;align-items:center;gap:12px;flex-shrink:0}.toolbar-divider{width:1px;height:20px;background:var(--border-color, #e2e8f0);margin:0 2px;flex-shrink:0}:host-context(.dark) .toolbar-divider{background:#475569}.toolbar-right{display:flex;align-items:center;gap:10px;flex-shrink:0}.status-bar{display:flex;align-items:center;height:100%;padding:0 16px;background:var(--status-bar-bg, #1e293b);color:#fff;font-size:12px;gap:20px;flex-shrink:0;height:36px}.stats-row{display:flex;align-items:center;gap:20px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.route-list-wrapper{position:absolute;top:10px;left:10px;bottom:10px;width:380px;z-index:20;pointer-events:none;display:flex;flex-direction:column}@media (max-width: 1024px){.route-list-wrapper{width:320px}}.route-list-wrapper>*{pointer-events:auto}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;border-radius:12px;border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #1f268712}:host-context(.dark) .list-loader{background:#0f172a66;border-color:#ffffff1a}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
2291
+ ], template: "<div class=\"center-area\">\n <div [formGroup]=\"filterForm\" class=\"toolbar flex flex-col sm:flex-row md:h-[55px] h-auto py-2 px-2 gap-3 items-center\">\n <div class=\"toolbar-left flex items-center gap-3 flex-1\">\n @if (activeSection() === 'Jobcode') {\n <div class=\"relative w-full sm:w-auto group mt-[25px]\">\n <input\n type=\"text\"\n [value]=\"displayDate()\"\n readonly\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"dateInput.showPicker()\"\n class=\"w-full pl-3 pr-10 py-2 rounded-lg border border-gray-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-blue focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer\"\n />\n <lucide-icon \n [img]=\"icons.Calendar\" \n [size]=\"18\" \n (click)=\"!coolmapService.isLoading() && dateInput.showPicker()\"\n [class.pointer-events-none]=\"coolmapService.isLoading()\"\n [class.opacity-50]=\"coolmapService.isLoading()\"\n class=\"absolute right-[6px] top-[5px] text-white-400 group-hover:text-brand-blue transition-colors cursor-pointer\"\n ></lucide-icon>\n <input\n #dateInput\n type=\"date\"\n [value]=\"dateValue()\"\n (change)=\"onDateChange($event)\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"absolute inset-0 w-0 h-0 opacity-0 pointer-events-none\"\n />\n </div>\n <span class=\"toolbar-divider hidden sm:flex h-6 w-[1px] bg-gray-200 dark:bg-slate-700\"></span>\n }\n @if (filters() && filters().length > 0) {\n <div class=\"flex flex-wrap gap-2 ml-2\">\n @for (filter of filters(); track filter.value + filter.type) {\n <div class=\"inline-flex items-center gap-1 px-2 py-2.5 rounded-xl bg-slate-200 dark:bg-slate-700 text-gray-800 dark:text-gray-200 text-xs font-medium border border-gray-300 dark:border-slate-600\">\n <span class=\"capitalize opacity-80\">{{ filter.type }}:</span> {{ filter.name }}\n <button type=\"button\" (click)=\"removeFilter(filter)\" class=\"hover:opacity-75 transition-opacity ml-1\">\n <lucide-icon [img]=\"icons.X\" [size]=\"12\"></lucide-icon>\n </button>\n </div>\n }\n </div>\n }\n <div #searchContainer class=\"relative items-center flex-1\">\n <lucide-icon [img]=\"icons.Search\" [size]=\"18\" class=\"absolute left-[0.55rem] top-[50%] -translate-y-1/2 text-gray-400\"></lucide-icon>\n <input\n type=\"text\"\n formControlName=\"search\"\n [attr.disabled]=\"coolmapService.isLoading() ? true : null\"\n placeholder=\"Search routes...\"\n class=\"w-full pl-10 pr-10 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-amber-500 focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n (focus)=\"onSearchFocus()\"\n />\n\n @if (filterForm.value.search) {\n <button (click)=\"filterForm.controls.search.setValue('')\" class=\"absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\">\n <lucide-icon [img]=\"icons.X\" [size]=\"16\"></lucide-icon>\n </button>\n }\n\n <!-- Autocomplete Dropdown -->\n @if (dropdownOpen() && filteredOptions().length > 0) {\n <div class=\"absolute z-70 left-0 right-0 top-full mt-1 max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n @for (option of filteredOptions(); track option.value + option.type) {\n <div (click)=\"selectFilter(option)\" class=\"px-4 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 cursor-pointer text-xs font-normal border-b border-gray-100 dark:border-slate-700 last:border-0 dark:text-white\">\n <span class=\"capitalize\">{{ option.type }}:</span>\n {{ option.label }}\n </div>\n }\n </div>\n } @else if (!coolmapService.isLoading() && (!filteredOptions() || filteredOptions().length === 0) && filterForm.value.search) {\n <div class=\"absolute z-70 left-0 right-0 top-full mt-1 p-4 text-center text-gray-400 text-sm bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n No results found.\n </div>\n }\n\n \n </div>\n </div>\n <div class=\"toolbar-right\">\n @if (selectedRouteIds().length > 0) {\n <button\n type=\"button\"\n (click)=\"clearSelection()\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n >\n Show all routes ({{ selectedRouteIds().length }})\n </button>\n }\n @if (activeSection() === 'ViewRoute') {\n <button\n type=\"button\"\n class=\"inline-flex items-center justify-center gap-2 px-4 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"openAddRouteModal()\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Add Route\n </button>\n }\n\n @if(activeSection() === 'Jobcode'){\n <button\n class=\"inline-flex items-center gap-2 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed relative group\"\n (click)=\"showRouteList = true\"\n [disabled]=\"coolmapService.isLoading()\">\n <lucide-icon [img]=\"icons.Route\" [size]=\"20\"></lucide-icon>\n <div\n class=\"absolute top-full right-0 mt-2 group-hover:block hidden bg-gray-800 dark:bg-white text-white dark:text-black text-[10px] rounded py-1 px-2 whitespace-nowrap\">\n Show Route List\n <div\n class=\"absolute -top-[8px] left-[60px] border-4 border-transparent border-b-gray-800 dark:border-b-white\">\n </div>\n </div>\n </button>}\n </div>\n </div>\n <div class=\"view-content\">\n <div class=\"full-view\">\n <div class=\"map-container\">\n <div class=\"mapbox-container\" #mapContainer></div>\n </div>\n </div>\n <!-- FOR JOBCODE -->\n @if (activeSection() === 'Jobcode') {\n <lib-job-code \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n (routeSelect)=\"toggleSelection($event)\">\n </lib-job-code>\n }\n\n <!-- FOR VIEWROUTE -->\n @if (activeSection() === 'ViewRoute') {\n <lib-view-route-list \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\"\n (editRoute)=\"openEditModal($event)\"\n ></lib-view-route-list>\n }\n </div>\n @if (config.repository === 'coolmap') {\n <div class=\"status-bar\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ masterStats().Done }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ masterStats().Incomplete }}</span>\n <span class=\"stat-label\">Incomplete</span>\n </div>\n\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ masterStats().Ongoing }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ masterStats().Open }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n </div>\n }\n</div>\n<lib-job-route-list \n [initialRoutes]=\"viewRoutesList()\"\n [(modalOpen)]=\"showRouteList\"\n [selectedRouteIds]=\"modalPlottedIds()\"\n (routeSelect)=\"toggleModalRoute($event)\"\n (masterToggleEvent)=\"modalMasterToggle($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n (shareRoute)=\"handleShareRoute($event)\"\n></lib-job-route-list>\n<lib-add-route \n [modalOpen]=\"addRouteModal\"\n (modalOpenChange)=\"onAddRouteModalChange($event)\"\n (routeSaved)=\"onRouteSaved($event)\"\n (routeDeleted)=\"onRouteDeleted($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n [routeData]=\"selectedRouteForEdit()\"\n></lib-add-route>\n\n@if (showShareModal()) {\n <lib-share-route\n [openShareRouteDetails]=\"shareRouteData()\"\n [userDetails]=\"userDetails\"\n (closePopupEmit)=\"showShareModal.set(false)\" class=\"relative\"\n ></lib-share-route>\n}\n\n<ag-toast-container></ag-toast-container>\n", styles: [":host{display:block;width:100%;height:100%;min-height:400px}.center-area{height:100%;display:flex;flex-direction:column;overflow:hidden}.view-content{flex:1;position:relative;overflow:hidden;z-index:10}.full-view{position:absolute;inset:0}.map-container,.mapbox-container{width:100%;height:100%}.toolbar{align-items:center;justify-content:space-between;background:var(--bg-primary, white);border-bottom:1px solid var(--border-color, #e2e8f0);flex-shrink:0;gap:8px;position:relative;z-index:12}:host-context(.dark) .toolbar{background:var(--bg-dark-primary, #1e293b);border-color:var(--border-dark, #334155);box-shadow:0 1px 3px #0000004d}.toolbar-left{display:flex;align-items:center;gap:12px;flex-shrink:0}.toolbar-divider{width:1px;height:20px;background:var(--border-color, #e2e8f0);margin:0 2px;flex-shrink:0}:host-context(.dark) .toolbar-divider{background:#475569}.toolbar-right{display:flex;align-items:center;gap:10px;flex-shrink:0}.status-bar{display:flex;align-items:center;height:100%;padding:0 16px;background:var(--status-bar-bg, #1e293b);color:#fff;font-size:12px;gap:20px;flex-shrink:0;height:36px}.stats-row{display:flex;align-items:center;gap:20px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.route-list-wrapper{position:absolute;top:10px;left:10px;bottom:10px;width:380px;z-index:20;pointer-events:none;display:flex;flex-direction:column}@media (max-width: 1024px){.route-list-wrapper{width:320px}}.route-list-wrapper>*{pointer-events:auto}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;border-radius:12px;border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #1f268712}:host-context(.dark) .list-loader{background:#0f172a66;border-color:#ffffff1a}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
2282
2292
  }], ctorParameters: () => [], propDecorators: { mobileMode: [{
2283
2293
  type: Input
2284
2294
  }], activeSection: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSection", required: false }] }], customerRepoDetails: [{