1import { 2 DocumentEditorComponent, 3 DocumentEditorModule 4} from "./chunk-4JQPTEOL.js"; 5import "./chunk-77V3AZII.js"; 6import { 7 readSync, 8 utils 9} from "./chunk-7A5OVJMY.js"; 10import { 11 require_lib 12} from "./chunk-72TKZXRX.js"; 13import { 14 require_jszip_min 15} from "./chunk-YTKJ5NH4.js"; 16import "./chunk-2YXXBSIT.js"; 17import { 18 LucideAngularComponent, 19 LucideAngularModule 20} from "./chunk-2RGPIWUP.js"; 21import "./chunk-F6FCAJLM.js"; 22import "./chunk-S7YLT3WB.js"; 23import { 24 DefaultValueAccessor, 25 FormsModule, 26 NgControlStatus, 27 NgModel 28} from "./chunk-4BWSLYHL.js"; 29import { 30 RfpService 31} from "./chunk-L3RGN6KE.js"; 32import { 33 getDocumentEditorImportURL 34} from "./chunk-7NJDBVIS.js"; 35import { 36 ActivatedRoute, 37 Router, 38 RouterModule 39} from "./chunk-RJBXOKCE.js"; 40import { 41 DomSanitizer 42} from "./chunk-HFMDFWBD.js"; 43import { 44 HttpClient 45} from "./chunk-TYP6PLA3.js"; 46import { 47 CommonModule, 48 Component, 49 HostListener, 50 Location, 51 NgClass, 52 NgForOf, 53 NgIf, 54 UpperCasePipe, 55 ViewChild, 56 firstValueFrom, 57 setClassMetadata, 58 ɵsetClassDebugInfo, 59 ɵɵadvance, 60 ɵɵclassProp, 61 ɵɵdefineComponent, 62 ɵɵdirectiveInject, 63 ɵɵelement, 64 ɵɵelementContainerEnd, 65 ɵɵelementContainerStart, 66 ɵɵelementEnd, 67 ɵɵelementStart, 68 ɵɵgetCurrentView, 69 ɵɵlistener, 70 ɵɵloadQuery, 71 ɵɵnextContext, 72 ɵɵpipe, 73 ɵɵpipeBind1, 74 ɵɵproperty, 75 ɵɵqueryRefresh, 76 ɵɵreference, 77 ɵɵresetView, 78 ɵɵresolveDocument, 79 ɵɵrestoreView, 80 ɵɵsanitizeHtml, 81 ɵɵsanitizeResourceUrl, 82 ɵɵtemplate, 83 ɵɵtemplateRefExtractor, 84 ɵɵtext, 85 ɵɵtextInterpolate, 86 ɵɵtextInterpolate1, 87 ɵɵtextInterpolate2, 88 ɵɵtwoWayBindingSet, 89 ɵɵtwoWayListener, 90 ɵɵtwoWayProperty, 91 ɵɵviewQuery 92} from "./chunk-6GJQIPT2.js"; 93import { 94 __async, 95 __toESM 96} from "./chunk-RK4NW2NR.js"; 97 98// src/app/pages/rfp-documents/rfp-documents.component.ts 99var mammoth = __toESM(require_lib()); 100var import_jszip = __toESM(require_jszip_min()); 101var _c0 = ["documentEditor"]; 102function RfpDocumentsComponent_div_1_Template(rf, ctx) { 103 if (rf & 1) { 104 \u0275\u0275elementStart(0, "div", 9); 105 \u0275\u0275element(1, "i", 10); 106 \u0275\u0275text(2, " Loading RFP documents\u2026 "); 107 \u0275\u0275elementEnd(); 108 } 109} 110function RfpDocumentsComponent_div_2_Template(rf, ctx) { 111 if (rf & 1) { 112 const _r1 = \u0275\u0275getCurrentView(); 113 \u0275\u0275elementStart(0, "div", 11)(1, "div", 12); 114 \u0275\u0275element(2, "i", 13); 115 \u0275\u0275elementStart(3, "p", 14); 116 \u0275\u0275text(4); 117 \u0275\u0275elementEnd(); 118 \u0275\u0275elementStart(5, "button", 15); 119 \u0275\u0275listener("click", function RfpDocumentsComponent_div_2_Template_button_click_5_listener() { 120 \u0275\u0275restoreView(_r1); 121 const ctx_r1 = \u0275\u0275nextContext(); 122 return \u0275\u0275resetView(ctx_r1.goToBack()); 123 }); 124 \u0275\u0275text(6, "Go Back"); 125 \u0275\u0275elementEnd()()(); 126 } 127 if (rf & 2) { 128 const ctx_r1 = \u0275\u0275nextContext(); 129 \u0275\u0275advance(4); 130 \u0275\u0275textInterpolate(ctx_r1.error); 131 } 132} 133function RfpDocumentsComponent_div_3_span_5_Template(rf, ctx) { 134 if (rf & 1) { 135 \u0275\u0275elementStart(0, "span", 62); 136 \u0275\u0275text(1); 137 \u0275\u0275elementEnd(); 138 } 139 if (rf & 2) { 140 const ctx_r1 = \u0275\u0275nextContext(2); 141 \u0275\u0275advance(); 142 \u0275\u0275textInterpolate1("- ", ctx_r1.rfpTitle, ""); 143 } 144} 145function RfpDocumentsComponent_div_3_ng_container_25_span_3_Template(rf, ctx) { 146 if (rf & 1) { 147 \u0275\u0275elementStart(0, "span", 66); 148 \u0275\u0275text(1, "/"); 149 \u0275\u0275elementEnd(); 150 } 151} 152function RfpDocumentsComponent_div_3_ng_container_25_span_4_Template(rf, ctx) { 153 if (rf & 1) { 154 \u0275\u0275elementStart(0, "span", 67); 155 \u0275\u0275text(1, "Amendments"); 156 \u0275\u0275elementEnd(); 157 } 158} 159function RfpDocumentsComponent_div_3_ng_container_25_Template(rf, ctx) { 160 if (rf & 1) { 161 const _r4 = \u0275\u0275getCurrentView(); 162 \u0275\u0275elementContainerStart(0); 163 \u0275\u0275elementStart(1, "span", 63); 164 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_ng_container_25_Template_span_click_1_listener() { 165 \u0275\u0275restoreView(_r4); 166 const ctx_r1 = \u0275\u0275nextContext(2);
167 return \u0275\u0275resetView(ctx_r1.setActiveTab("initial")); 168 }); 169 \u0275\u0275text(2, "RFP Package"); 170 \u0275\u0275elementEnd(); 171 \u0275\u0275template(3, RfpDocumentsComponent_div_3_ng_container_25_span_3_Template, 2, 0, "span", 64)(4, RfpDocumentsComponent_div_3_ng_container_25_span_4_Template, 2, 0, "span", 65); 172 \u0275\u0275elementContainerEnd(); 173 } 174 if (rf & 2) { 175 const ctx_r1 = \u0275\u0275nextContext(2); 176 \u0275\u0275advance(); 177 \u0275\u0275classProp("bc-active", ctx_r1.activeTab === "initial"); 178 \u0275\u0275advance(2); 179 \u0275\u0275property("ngIf", ctx_r1.activeTab === "amendments"); 180 \u0275\u0275advance(); 181 \u0275\u0275property("ngIf", ctx_r1.activeTab === "amendments"); 182 } 183} 184function RfpDocumentsComponent_div_3_ng_template_26_Template(rf, ctx) { 185 if (rf & 1) { 186 \u0275\u0275elementStart(0, "span", 67); 187 \u0275\u0275text(1, "All Documents"); 188 \u0275\u0275elementEnd(); 189 } 190} 191function RfpDocumentsComponent_div_3_span_35_Template(rf, ctx) { 192 if (rf & 1) { 193 \u0275\u0275elementStart(0, "span"); 194 \u0275\u0275text(1); 195 \u0275\u0275elementEnd(); 196 } 197 if (rf & 2) { 198 const ctx_r1 = \u0275\u0275nextContext(2); 199 \u0275\u0275advance(); 200 \u0275\u0275textInterpolate1(" (", ctx_r1.selectedType, ")"); 201 } 202} 203function RfpDocumentsComponent_div_3_div_36_div_3_Template(rf, ctx) { 204 if (rf & 1) { 205 const _r6 = \u0275\u0275getCurrentView(); 206 \u0275\u0275elementStart(0, "div", 71); 207 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_div_36_div_3_Template_div_click_0_listener() { 208 const t_r7 = \u0275\u0275restoreView(_r6).$implicit; 209 const ctx_r1 = \u0275\u0275nextContext(3); 210 return \u0275\u0275resetView(ctx_r1.selectFilter("type", t_r7)); 211 }); 212 \u0275\u0275text(1); 213 \u0275\u0275elementEnd(); 214 } 215 if (rf & 2) { 216 const t_r7 = ctx.$implicit; 217 const ctx_r1 = \u0275\u0275nextContext(3); 218 \u0275\u0275classProp("selected", ctx_r1.selectedType === t_r7); 219 \u0275\u0275property("hidden", t_r7 === "All"); 220 \u0275\u0275advance(); 221 \u0275\u0275textInterpolate(t_r7); 222 } 223} 224function RfpDocumentsComponent_div_3_div_36_Template(rf, ctx) { 225 if (rf & 1) { 226 const _r5 = \u0275\u0275getCurrentView(); 227 \u0275\u0275elementStart(0, "div", 68); 228 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_div_36_Template_div_click_0_listener($event) { 229 \u0275\u0275restoreView(_r5); 230 return \u0275\u0275resetView($event.stopPropagation()); 231 }); 232 \u0275\u0275elementStart(1, "div", 69); 233 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_div_36_Template_div_click_1_listener() { 234 \u0275\u0275restoreView(_r5); 235 const ctx_r1 = \u0275\u0275nextContext(2); 236 return \u0275\u0275resetView(ctx_r1.selectFilter("type", "All")); 237 }); 238 \u0275\u0275text(2, "All"); 239 \u0275\u0275elementEnd(); 240 \u0275\u0275template(3, RfpDocumentsComponent_div_3_div_36_div_3_Template, 2, 4, "div", 70); 241 \u0275\u0275elementEnd(); 242 } 243 if (rf & 2) { 244 const ctx_r1 = \u0275\u0275nextContext(2); 245 \u0275\u0275advance(); 246 \u0275\u0275classProp("selected", ctx_r1.selectedType === "All"); 247 \u0275\u0275advance(2); 248 \u0275\u0275property("ngForOf", ctx_r1.availableTypes); 249 } 250} 251function RfpDocumentsComponent_div_3_button_37_Template(rf, ctx) { 252 if (rf & 1) { 253 const _r8 = \u0275\u0275getCurrentView(); 254 \u0275\u0275elementStart(0, "button", 72); 255 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_button_37_Template_button_click_0_listener() { 256 \u0275\u0275restoreView(_r8); 257 const ctx_r1 = \u0275\u0275nextContext(2); 258 return \u0275\u0275resetView(ctx_r1.resetFilters()); 259 }); 260 \u0275\u0275element(1, "i", 73); 261 \u0275\u0275text(2, " Clear "); 262 \u0275\u0275elementEnd(); 263 } 264} 265function RfpDocumentsComponent_div_3_span_49_Template(rf, ctx) { 266 if (rf & 1) { 267 \u0275\u0275elementStart(0, "span", 74); 268 \u0275\u0275text(1); 269 \u0275\u0275elementEnd(); 270 } 271 if (rf & 2) { 272 const ctx_r1 = \u0275\u0275nextContext(2); 273 \u0275\u0275advance(); 274 \u0275\u0275textInterpolate(ctx_r1.files.length); 275 } 276} 277function RfpDocumentsComponent_div_3_div_50_span_6_Template(rf, ctx) { 278 if (rf & 1) { 279 \u0275\u0275elementStart(0, "span", 74); 280 \u0275\u0275text(1); 281 \u0275\u0275elementEnd(); 282 } 283 if (rf & 2) { 284 const ctx_r1 = \u0275\u0275nextContext(3); 285 \u0275\u0275advance(); 286 \u0275\u0275textInterpolate(ctx_r1.amendments.length); 287 } 288} 289function RfpDocumentsComponent_div_3_div_50_Template(rf, ctx) { 290 if (rf & 1) { 291 const _r9 = \u0275\u0275getCurrentView(); 292 \u0275\u0275elementStart(0, "div", 47); 293 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_div_50_Template_div_click_0_listener() { 294 \u0275\u0275restoreView(_r9); 295 const ctx_r1 = \u0275\u0275nextContext(2);
296 return \u0275\u0275resetView(ctx_r1.setActiveTab("amendments")); 297 }); 298 \u0275\u0275elementStart(1, "span", 48); 299 \u0275\u0275element(2, "i", 49); 300 \u0275\u0275elementEnd(); 301 \u0275\u0275element(3, "lucide-icon", 75); 302 \u0275\u0275elementStart(4, "span", 51); 303 \u0275\u0275text(5, "Amendments"); 304 \u0275\u0275elementEnd(); 305 \u0275\u0275template(6, RfpDocumentsComponent_div_3_div_50_span_6_Template, 2, 1, "span", 52); 306 \u0275\u0275elementEnd(); 307 } 308 if (rf & 2) { 309 const ctx_r1 = \u0275\u0275nextContext(2); 310 \u0275\u0275classProp("selected", ctx_r1.activeTab === "amendments"); 311 \u0275\u0275advance(3); 312 \u0275\u0275property("size", 16); 313 \u0275\u0275advance(3); 314 \u0275\u0275property("ngIf", ctx_r1.amendments.length); 315 } 316} 317function RfpDocumentsComponent_div_3_span_55_Template(rf, ctx) { 318 if (rf & 1) { 319 \u0275\u0275elementStart(0, "span", 76); 320 \u0275\u0275text(1); 321 \u0275\u0275elementEnd(); 322 } 323 if (rf & 2) { 324 const ctx_r1 = \u0275\u0275nextContext(2); 325 \u0275\u0275advance(); 326 \u0275\u0275textInterpolate2("", ctx_r1.filteredFiles.length, " item", ctx_r1.filteredFiles.length !== 1 ? "s" : "", ""); 327 } 328} 329function RfpDocumentsComponent_div_3_button_56_Template(rf, ctx) { 330 if (rf & 1) { 331 const _r10 = \u0275\u0275getCurrentView(); 332 \u0275\u0275elementStart(0, "button", 77); 333 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_button_56_Template_button_click_0_listener() { 334 \u0275\u0275restoreView(_r10); 335 const ctx_r1 = \u0275\u0275nextContext(2); 336 return \u0275\u0275resetView(ctx_r1.downloadAllFiles()); 337 }); 338 \u0275\u0275element(1, "i", 78); 339 \u0275\u0275text(2); 340 \u0275\u0275elementEnd(); 341 } 342 if (rf & 2) { 343 const ctx_r1 = \u0275\u0275nextContext(2); 344 \u0275\u0275property("disabled", ctx_r1.isDownloadingAll); 345 \u0275\u0275advance(); 346 \u0275\u0275property("ngClass", ctx_r1.isDownloadingAll ? "fa-spinner fa-spin" : "fa-download"); 347 \u0275\u0275advance(); 348 \u0275\u0275textInterpolate1(" ", ctx_r1.isDownloadingAll ? "Downloading..." : "Download All", " "); 349 } 350} 351function RfpDocumentsComponent_div_3_div_57_table_1_tr_12_Template(rf, ctx) { 352 if (rf & 1) { 353 const _r11 = \u0275\u0275getCurrentView(); 354 \u0275\u0275elementStart(0, "tr", 87); 355 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_div_57_table_1_tr_12_Template_tr_click_0_listener() { 356 const file_r12 = \u0275\u0275restoreView(_r11).$implicit; 357 const ctx_r1 = \u0275\u0275nextContext(4); 358 return \u0275\u0275resetView(ctx_r1.selectFile(file_r12)); 359 })("dblclick", function RfpDocumentsComponent_div_3_div_57_table_1_tr_12_Template_tr_dblclick_0_listener() { 360 const file_r12 = \u0275\u0275restoreView(_r11).$implicit; 361 const ctx_r1 = \u0275\u0275nextContext(4); 362 return \u0275\u0275resetView(ctx_r1.previewFolderFile(file_r12)); 363 }); 364 \u0275\u0275elementStart(1, "td", 82)(2, "div", 88)(3, "div", 89); 365 \u0275\u0275element(4, "lucide-icon", 90); 366 \u0275\u0275elementEnd(); 367 \u0275\u0275elementStart(5, "span", 91); 368 \u0275\u0275text(6); 369 \u0275\u0275elementEnd()()(); 370 \u0275\u0275elementStart(7, "td", 83); 371 \u0275\u0275text(8); 372 \u0275\u0275pipe(9, "uppercase"); 373 \u0275\u0275elementEnd(); 374 \u0275\u0275elementStart(10, "td", 84); 375 \u0275\u0275text(11); 376 \u0275\u0275elementEnd(); 377 \u0275\u0275elementStart(12, "td", 85)(13, "div", 92); 378 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_div_57_table_1_tr_12_Template_div_click_13_listener($event) { 379 \u0275\u0275restoreView(_r11); 380 return \u0275\u0275resetView($event.stopPropagation()); 381 }); 382 \u0275\u0275elementStart(14, "button", 93); 383 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_div_57_table_1_tr_12_Template_button_click_14_listener() { 384 const file_r12 = \u0275\u0275restoreView(_r11).$implicit; 385 const ctx_r1 = \u0275\u0275nextContext(4); 386 return \u0275\u0275resetView(ctx_r1.previewFolderFile(file_r12)); 387 }); 388 \u0275\u0275element(15, "i", 94); 389 \u0275\u0275elementEnd(); 390 \u0275\u0275elementStart(16, "button", 95); 391 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_div_57_table_1_tr_12_Template_button_click_16_listener() { 392 const file_r12 = \u0275\u0275restoreView(_r11).$implicit; 393 const ctx_r1 = \u0275\u0275nextContext(4);
394 return \u0275\u0275resetView(ctx_r1.downloadFolderFile(file_r12)); 395 }); 396 \u0275\u0275element(17, "i", 96); 397 \u0275\u0275elementEnd()()()(); 398 } 399 if (rf & 2) { 400 const file_r12 = ctx.$implicit; 401 const ctx_r1 = \u0275\u0275nextContext(4); 402 \u0275\u0275classProp("row-selected", (ctx_r1.selectedFile == null ? null : ctx_r1.selectedFile.id) === file_r12.id); 403 \u0275\u0275advance(3); 404 \u0275\u0275property("ngClass", ctx_r1.getFileIconClass(file_r12.fileType)); 405 \u0275\u0275advance(); 406 \u0275\u0275property("name", ctx_r1.getFileIcon(file_r12.fileType))("size", 16); 407 \u0275\u0275advance(); 408 \u0275\u0275property("title", file_r12.fileName); 409 \u0275\u0275advance(); 410 \u0275\u0275textInterpolate(file_r12.fileName); 411 \u0275\u0275advance(2); 412 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(9, 9, file_r12.fileType)); 413 \u0275\u0275advance(3); 414 \u0275\u0275textInterpolate(file_r12.uploadedDate); 415 } 416} 417function RfpDocumentsComponent_div_3_div_57_table_1_Template(rf, ctx) { 418 if (rf & 1) { 419 \u0275\u0275elementStart(0, "table", 81)(1, "thead")(2, "tr")(3, "th", 82); 420 \u0275\u0275text(4, "Name"); 421 \u0275\u0275elementEnd(); 422 \u0275\u0275elementStart(5, "th", 83); 423 \u0275\u0275text(6, "Type"); 424 \u0275\u0275elementEnd(); 425 \u0275\u0275elementStart(7, "th", 84); 426 \u0275\u0275text(8, "Created/Uploaded Date"); 427 \u0275\u0275elementEnd(); 428 \u0275\u0275elementStart(9, "th", 85); 429 \u0275\u0275text(10, "Actions"); 430 \u0275\u0275elementEnd()()(); 431 \u0275\u0275elementStart(11, "tbody"); 432 \u0275\u0275template(12, RfpDocumentsComponent_div_3_div_57_table_1_tr_12_Template, 18, 11, "tr", 86); 433 \u0275\u0275elementEnd()(); 434 } 435 if (rf & 2) { 436 const ctx_r1 = \u0275\u0275nextContext(3); 437 \u0275\u0275advance(12); 438 \u0275\u0275property("ngForOf", ctx_r1.filteredFiles); 439 } 440} 441function RfpDocumentsComponent_div_3_div_57_ng_template_2_Template(rf, ctx) { 442 if (rf & 1) { 443 \u0275\u0275elementStart(0, "div", 97); 444 \u0275\u0275element(1, "lucide-icon", 98); 445 \u0275\u0275elementStart(2, "p"); 446 \u0275\u0275text(3); 447 \u0275\u0275elementEnd()(); 448 } 449 if (rf & 2) { 450 const ctx_r1 = \u0275\u0275nextContext(3); 451 \u0275\u0275advance(); 452 \u0275\u0275property("size", 48); 453 \u0275\u0275advance(2); 454 \u0275\u0275textInterpolate(ctx_r1.isSled2 ? ctx_r1.activeTab === "initial" ? "No documents found matching search criteria." : "No amendments found for this RFP." : "No documents found matching search criteria."); 455 } 456} 457function RfpDocumentsComponent_div_3_div_57_Template(rf, ctx) { 458 if (rf & 1) { 459 \u0275\u0275elementStart(0, "div", 79); 460 \u0275\u0275template(1, RfpDocumentsComponent_div_3_div_57_table_1_Template, 13, 1, "table", 80)(2, RfpDocumentsComponent_div_3_div_57_ng_template_2_Template, 4, 2, "ng-template", null, 1, \u0275\u0275templateRefExtractor); 461 \u0275\u0275elementEnd(); 462 } 463 if (rf & 2) { 464 const emptyState_r13 = \u0275\u0275reference(3); 465 const ctx_r1 = \u0275\u0275nextContext(2); 466 \u0275\u0275advance(); 467 \u0275\u0275property("ngIf", ctx_r1.filteredFiles.length)("ngIfElse", emptyState_r13); 468 } 469} 470function RfpDocumentsComponent_div_3_div_58_div_1_div_1_Template(rf, ctx) { 471 if (rf & 1) { 472 const _r14 = \u0275\u0275getCurrentView(); 473 \u0275\u0275elementStart(0, "div", 103); 474 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_div_58_div_1_div_1_Template_div_click_0_listener() { 475 const file_r15 = \u0275\u0275restoreView(_r14).$implicit; 476 const ctx_r1 = \u0275\u0275nextContext(4); 477 return \u0275\u0275resetView(ctx_r1.selectFile(file_r15)); 478 })("dblclick", function RfpDocumentsComponent_div_3_div_58_div_1_div_1_Template_div_dblclick_0_listener() { 479 const file_r15 = \u0275\u0275restoreView(_r14).$implicit; 480 const ctx_r1 = \u0275\u0275nextContext(4); 481 return \u0275\u0275resetView(ctx_r1.previewFolderFile(file_r15)); 482 }); 483 \u0275\u0275elementStart(1, "div", 104); 484 \u0275\u0275element(2, "lucide-icon", 90); 485 \u0275\u0275elementEnd(); 486 \u0275\u0275elementStart(3, "span", 105); 487 \u0275\u0275text(4); 488 \u0275\u0275elementEnd()(); 489 } 490 if (rf & 2) { 491 const file_r15 = ctx.$implicit; 492 const ctx_r1 = \u0275\u0275nextContext(4); 493 \u0275\u0275classProp("card-selected", (ctx_r1.selectedFile == null ? null : ctx_r1.selectedFile.id) === file_r15.id); 494 \u0275\u0275advance(); 495 \u0275\u0275property("ngClass", ctx_r1.getFileIconClass(file_r15.fileType)); 496 \u0275\u0275advance(); 497 \u0275\u0275property("name", ctx_r1.getFileIcon(file_r15.fileType))("size", 32); 498 \u0275\u0275advance(); 499 \u0275\u0275property("title", file_r15.fileName); 500 \u0275\u0275advance(); 501 \u0275\u0275textInterpolate(file_r15.fileName); 502 } 503} 504function RfpDocumentsComponent_div_3_div_58_div_1_Template(rf, ctx) { 505 if (rf & 1) { 506 \u0275\u0275elementStart(0, "div", 101); 507 \u0275\u0275template(1, RfpDocumentsComponent_div_3_div_58_div_1_div_1_Template, 5, 7, "div", 102); 508 \u0275\u0275elementEnd(); 509 } 510 if (rf & 2) { 511 const ctx_r1 = \u0275\u0275nextContext(3); 512 \u0275\u0275advance(); 513 \u0275\u0275property("ngForOf", ctx_r1.filteredFiles); 514 } 515} 516function RfpDocumentsComponent_div_3_div_58_ng_template_2_Template(rf, ctx) { 517 if (rf & 1) { 518 \u0275\u0275elementStart(0, "div", 97); 519 \u0275\u0275element(1, "lucide-icon", 98); 520 \u0275\u0275elementStart(2, "p"); 521 \u0275\u0275text(3); 522 \u0275\u0275elementEnd()(); 523 } 524 if (rf & 2) { 525 const ctx_r1 = \u0275\u0275nextContext(3); 526 \u0275\u0275advance(); 527 \u0275\u0275property("size", 48); 528 \u0275\u0275advance(2); 529 \u0275\u0275textInterpolate(ctx_r1.isSled2 ? ctx_r1.activeTab === "initial" ? "No documents found matching search criteria." : "No amendments found for this RFP." : "No documents found matching search criteria."); 530 } 531} 532function RfpDocumentsComponent_div_3_div_58_Template(rf, ctx) { 533 if (rf & 1) { 534 \u0275\u0275elementStart(0, "div", 99); 535 \u0275\u0275template(1, RfpDocumentsComponent_div_3_div_58_div_1_Template, 2, 1, "div", 100)(2, RfpDocumentsComponent_div_3_div_58_ng_template_2_Template, 4, 2, "ng-template", null, 2, \u0275\u0275templateRefExtractor); 536 \u0275\u0275elementEnd(); 537 } 538 if (rf & 2) { 539 const emptyGrid_r16 = \u0275\u0275reference(3); 540 const ctx_r1 = \u0275\u0275nextContext(2); 541 \u0275\u0275advance(); 542 \u0275\u0275property("ngIf", ctx_r1.filteredFiles.length)("ngIfElse", emptyGrid_r16); 543 } 544} 545function RfpDocumentsComponent_div_3_aside_59_p_7_Template(rf, ctx) { 546 if (rf & 1) { 547 \u0275\u0275elementStart(0, "p", 116); 548 \u0275\u0275text(1); 549 \u0275\u0275elementEnd(); 550 } 551 if (rf & 2) { 552 const ctx_r1 = \u0275\u0275nextContext(3); 553 \u0275\u0275advance(); 554 \u0275\u0275textInterpolate1(" Created: ", ctx_r1.selectedFile.uploadedDate, " "); 555 } 556} 557function RfpDocumentsComponent_div_3_aside_59_Template(rf, ctx) { 558 if (rf & 1) { 559 const _r17 = \u0275\u0275getCurrentView(); 560 \u0275\u0275elementStart(0, "aside", 106)(1, "div", 107)(2, "div", 108); 561 \u0275\u0275element(3, "lucide-icon", 90); 562 \u0275\u0275elementEnd(); 563 \u0275\u0275elementStart(4, "div", 109)(5, "p", 110); 564 \u0275\u0275text(6); 565 \u0275\u0275elementEnd(); 566 \u0275\u0275template(7, RfpDocumentsComponent_div_3_aside_59_p_7_Template, 2, 1, "p", 111); 567 \u0275\u0275elementEnd(); 568 \u0275\u0275elementStart(8, "button", 112); 569 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_aside_59_Template_button_click_8_listener() { 570 \u0275\u0275restoreView(_r17); 571 const ctx_r1 = \u0275\u0275nextContext(2);
572 return \u0275\u0275resetView(ctx_r1.closeFileDetails()); 573 }); 574 \u0275\u0275element(9, "i", 73); 575 \u0275\u0275elementEnd()(); 576 \u0275\u0275elementStart(10, "div", 113)(11, "button", 114); 577 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_aside_59_Template_button_click_11_listener() { 578 \u0275\u0275restoreView(_r17); 579 const ctx_r1 = \u0275\u0275nextContext(2); 580 return \u0275\u0275resetView(ctx_r1.downloadFolderFile(ctx_r1.selectedFile)); 581 }); 582 \u0275\u0275element(12, "i", 78); 583 \u0275\u0275text(13); 584 \u0275\u0275elementEnd(); 585 \u0275\u0275elementStart(14, "button", 115); 586 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_aside_59_Template_button_click_14_listener() { 587 \u0275\u0275restoreView(_r17); 588 const ctx_r1 = \u0275\u0275nextContext(2); 589 return \u0275\u0275resetView(ctx_r1.previewFolderFile(ctx_r1.selectedFile)); 590 }); 591 \u0275\u0275element(15, "i", 78); 592 \u0275\u0275text(16); 593 \u0275\u0275elementEnd()()(); 594 } 595 if (rf & 2) { 596 const ctx_r1 = \u0275\u0275nextContext(2); 597 \u0275\u0275advance(2); 598 \u0275\u0275property("ngClass", ctx_r1.getFileIconClass(ctx_r1.selectedFile.fileType)); 599 \u0275\u0275advance(); 600 \u0275\u0275property("name", ctx_r1.getFileIcon(ctx_r1.selectedFile.fileType))("size", 32); 601 \u0275\u0275advance(2); 602 \u0275\u0275property("title", ctx_r1.selectedFile.fileName); 603 \u0275\u0275advance(); 604 \u0275\u0275textInterpolate(ctx_r1.selectedFile.fileName); 605 \u0275\u0275advance(); 606 \u0275\u0275property("ngIf", ctx_r1.selectedFile.uploadedDate && ctx_r1.selectedFile.uploadedDate !== "N/A"); 607 \u0275\u0275advance(4); 608 \u0275\u0275property("disabled", ctx_r1.isDownloadingFile || ctx_r1.isOpeningFile); 609 \u0275\u0275advance(); 610 \u0275\u0275property("ngClass", ctx_r1.isDownloadingFile ? "fa-spinner fa-spin" : "fa-download"); 611 \u0275\u0275advance(); 612 \u0275\u0275textInterpolate1(" ", ctx_r1.isDownloadingFile ? "Downloading..." : "Download", " "); 613 \u0275\u0275advance(); 614 \u0275\u0275property("disabled", ctx_r1.isDownloadingFile || ctx_r1.isOpeningFile); 615 \u0275\u0275advance(); 616 \u0275\u0275property("ngClass", ctx_r1.isOpeningFile ? "fa-spinner fa-spin" : "fa-eye"); 617 \u0275\u0275advance(); 618 \u0275\u0275textInterpolate1(" ", ctx_r1.isOpeningFile ? "Opening..." : "Open", " "); 619 } 620} 621function RfpDocumentsComponent_div_3_Template(rf, ctx) { 622 if (rf & 1) { 623 const _r3 = \u0275\u0275getCurrentView(); 624 \u0275\u0275elementStart(0, "div", 16)(1, "div", 17); 625 \u0275\u0275element(2, "i", 18); 626 \u0275\u0275elementStart(3, "span", 19); 627 \u0275\u0275text(4, "RFP Documents "); 628 \u0275\u0275template(5, RfpDocumentsComponent_div_3_span_5_Template, 2, 1, "span", 20); 629 \u0275\u0275elementEnd()(); 630 \u0275\u0275elementStart(6, "div", 21)(7, "div", 22)(8, "button", 23); 631 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_Template_button_click_8_listener() { 632 \u0275\u0275restoreView(_r3); 633 const ctx_r1 = \u0275\u0275nextContext(); 634 return \u0275\u0275resetView(ctx_r1.gotoListView()); 635 }); 636 \u0275\u0275element(9, "i", 24); 637 \u0275\u0275elementStart(10, "span"); 638 \u0275\u0275text(11, "Details"); 639 \u0275\u0275elementEnd()(); 640 \u0275\u0275elementStart(12, "button", 23); 641 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_Template_button_click_12_listener() { 642 \u0275\u0275restoreView(_r3); 643 const ctx_r1 = \u0275\u0275nextContext(); 644 return \u0275\u0275resetView(ctx_r1.gotoGridView()); 645 }); 646 \u0275\u0275element(13, "i", 25); 647 \u0275\u0275elementStart(14, "span"); 648 \u0275\u0275text(15, "Icons"); 649 \u0275\u0275elementEnd()()(); 650 \u0275\u0275element(16, "div", 26); 651 \u0275\u0275elementStart(17, "div", 27)(18, "div", 28); 652 \u0275\u0275element(19, "i", 29); 653 \u0275\u0275elementStart(20, "input", 30); 654 \u0275\u0275twoWayListener("ngModelChange", function RfpDocumentsComponent_div_3_Template_input_ngModelChange_20_listener($event) { 655 \u0275\u0275restoreView(_r3); 656 const ctx_r1 = \u0275\u0275nextContext(); 657 \u0275\u0275twoWayBindingSet(ctx_r1.searchTerm, $event) || (ctx_r1.searchTerm = $event);
658 return \u0275\u0275resetView($event); 659 }); 660 \u0275\u0275listener("ngModelChange", function RfpDocumentsComponent_div_3_Template_input_ngModelChange_20_listener() { 661 \u0275\u0275restoreView(_r3); 662 const ctx_r1 = \u0275\u0275nextContext(); 663 return \u0275\u0275resetView(ctx_r1.filterFiles()); 664 }); 665 \u0275\u0275elementEnd()()()(); 666 \u0275\u0275elementStart(21, "div", 31)(22, "button", 32); 667 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_Template_button_click_22_listener() { 668 \u0275\u0275restoreView(_r3); 669 const ctx_r1 = \u0275\u0275nextContext(); 670 return \u0275\u0275resetView(ctx_r1.setActiveTab("initial")); 671 }); 672 \u0275\u0275element(23, "lucide-icon", 33); 673 \u0275\u0275elementEnd(); 674 \u0275\u0275elementStart(24, "div", 34); 675 \u0275\u0275template(25, RfpDocumentsComponent_div_3_ng_container_25_Template, 5, 4, "ng-container", 35)(26, RfpDocumentsComponent_div_3_ng_template_26_Template, 2, 0, "ng-template", null, 0, \u0275\u0275templateRefExtractor); 676 \u0275\u0275elementEnd(); 677 \u0275\u0275elementStart(28, "div", 36)(29, "span", 37); 678 \u0275\u0275text(30, "Filters:"); 679 \u0275\u0275elementEnd(); 680 \u0275\u0275elementStart(31, "div", 38)(32, "button", 39); 681 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_Template_button_click_32_listener($event) { 682 \u0275\u0275restoreView(_r3); 683 const ctx_r1 = \u0275\u0275nextContext(); 684 return \u0275\u0275resetView(ctx_r1.toggleDropdown("type", $event)); 685 }); 686 \u0275\u0275element(33, "i", 40); 687 \u0275\u0275text(34, " Type"); 688 \u0275\u0275template(35, RfpDocumentsComponent_div_3_span_35_Template, 2, 1, "span", 41); 689 \u0275\u0275elementEnd(); 690 \u0275\u0275template(36, RfpDocumentsComponent_div_3_div_36_Template, 4, 3, "div", 42); 691 \u0275\u0275elementEnd(); 692 \u0275\u0275template(37, RfpDocumentsComponent_div_3_button_37_Template, 3, 0, "button", 43); 693 \u0275\u0275elementEnd()(); 694 \u0275\u0275elementStart(38, "div", 44)(39, "nav", 45)(40, "div", 46)(41, "span"); 695 \u0275\u0275text(42, "Navigation"); 696 \u0275\u0275elementEnd()(); 697 \u0275\u0275elementStart(43, "div", 47); 698 \u0275\u0275listener("click", function RfpDocumentsComponent_div_3_Template_div_click_43_listener() { 699 \u0275\u0275restoreView(_r3); 700 const ctx_r1 = \u0275\u0275nextContext(); 701 return \u0275\u0275resetView(ctx_r1.setActiveTab("initial")); 702 }); 703 \u0275\u0275elementStart(44, "span", 48); 704 \u0275\u0275element(45, "i", 49); 705 \u0275\u0275elementEnd(); 706 \u0275\u0275element(46, "lucide-icon", 50); 707 \u0275\u0275elementStart(47, "span", 51); 708 \u0275\u0275text(48); 709 \u0275\u0275elementEnd(); 710 \u0275\u0275template(49, RfpDocumentsComponent_div_3_span_49_Template, 2, 1, "span", 52); 711 \u0275\u0275elementEnd(); 712 \u0275\u0275template(50, RfpDocumentsComponent_div_3_div_50_Template, 7, 4, "div", 53); 713 \u0275\u0275elementEnd(); 714 \u0275\u0275elementStart(51, "div", 54)(52, "div", 55)(53, "span", 56); 715 \u0275\u0275text(54); 716 \u0275\u0275elementEnd(); 717 \u0275\u0275template(55, RfpDocumentsComponent_div_3_span_55_Template, 2, 2, "span", 57)(56, RfpDocumentsComponent_div_3_button_56_Template, 3, 3, "button", 58); 718 \u0275\u0275elementEnd(); 719 \u0275\u0275template(57, RfpDocumentsComponent_div_3_div_57_Template, 4, 2, "div", 59)(58, RfpDocumentsComponent_div_3_div_58_Template, 4, 2, "div", 60); 720 \u0275\u0275elementEnd(); 721 \u0275\u0275template(59, RfpDocumentsComponent_div_3_aside_59_Template, 17, 12, "aside", 61); 722 \u0275\u0275elementEnd()(); 723 } 724 if (rf & 2) { 725 const standardBreadcrumb_r18 = \u0275\u0275reference(27); 726 const ctx_r1 = \u0275\u0275nextContext(); 727 \u0275\u0275advance(5); 728 \u0275\u0275property("ngIf", ctx_r1.rfpTitle); 729 \u0275\u0275advance(3); 730 \u0275\u0275classProp("active", ctx_r1.isList); 731 \u0275\u0275advance(4); 732 \u0275\u0275classProp("active", ctx_r1.isGrid); 733 \u0275\u0275advance(8); 734 \u0275\u0275twoWayProperty("ngModel", ctx_r1.searchTerm); 735 \u0275\u0275advance(2); 736 \u0275\u0275property("title", ctx_r1.isSled2 ? "RFP Package" : "All Files"); 737 \u0275\u0275advance(); 738 \u0275\u0275property("size", 16); 739 \u0275\u0275advance(2); 740 \u0275\u0275property("ngIf", ctx_r1.isSled2)("ngIfElse", standardBreadcrumb_r18); 741 \u0275\u0275advance(7); 742 \u0275\u0275classProp("active", ctx_r1.selectedType !== "All"); 743 \u0275\u0275advance(3); 744 \u0275\u0275property("ngIf", ctx_r1.selectedType !== "All"); 745 \u0275\u0275advance(); 746 \u0275\u0275property("ngIf", ctx_r1.activeDropdown === "type"); 747 \u0275\u0275advance(); 748 \u0275\u0275property("ngIf", ctx_r1.selectedType !== "All" || ctx_r1.searchTerm); 749 \u0275\u0275advance(6); 750 \u0275\u0275classProp("selected", ctx_r1.activeTab === "initial"); 751 \u0275\u0275advance(3); 752 \u0275\u0275property("size", 16); 753 \u0275\u0275advance(2); 754 \u0275\u0275textInterpolate(ctx_r1.isSled2 ? "RFP Package" : "All RFP Files"); 755 \u0275\u0275advance(); 756 \u0275\u0275property("ngIf", ctx_r1.files.length); 757 \u0275\u0275advance(); 758 \u0275\u0275property("ngIf", ctx_r1.isSled2); 759 \u0275\u0275advance();
760 \u0275\u0275classProp("has-details", !!ctx_r1.selectedFile); 761 \u0275\u0275advance(3); 762 \u0275\u0275textInterpolate(ctx_r1.isSled2 ? ctx_r1.activeTab === "initial" ? "RFP Package" : "RFP Amendments" : "RFP Source Files"); 763 \u0275\u0275advance(); 764 \u0275\u0275property("ngIf", ctx_r1.filteredFiles.length); 765 \u0275\u0275advance(); 766 \u0275\u0275property("ngIf", (ctx_r1.activeTab === "amendments" ? ctx_r1.amendments : ctx_r1.files).length); 767 \u0275\u0275advance(); 768 \u0275\u0275property("ngIf", ctx_r1.isList); 769 \u0275\u0275advance(); 770 \u0275\u0275property("ngIf", ctx_r1.isGrid); 771 \u0275\u0275advance(); 772 \u0275\u0275property("ngIf", ctx_r1.selectedFile); 773 } 774} 775function RfpDocumentsComponent_div_4_div_11_Template(rf, ctx) { 776 if (rf & 1) { 777 const _r20 = \u0275\u0275getCurrentView(); 778 \u0275\u0275elementStart(0, "div", 131)(1, "p", 132); 779 \u0275\u0275text(2, "\u26A0\uFE0F Unable to open file"); 780 \u0275\u0275elementEnd(); 781 \u0275\u0275elementStart(3, "p", 14); 782 \u0275\u0275text(4); 783 \u0275\u0275elementEnd(); 784 \u0275\u0275elementStart(5, "button", 133); 785 \u0275\u0275listener("click", function RfpDocumentsComponent_div_4_div_11_Template_button_click_5_listener() { 786 \u0275\u0275restoreView(_r20); 787 const ctx_r1 = \u0275\u0275nextContext(2); 788 return \u0275\u0275resetView(ctx_r1.closePreview()); 789 }); 790 \u0275\u0275text(6, "Close"); 791 \u0275\u0275elementEnd()(); 792 } 793 if (rf & 2) { 794 const ctx_r1 = \u0275\u0275nextContext(2); 795 \u0275\u0275advance(4); 796 \u0275\u0275textInterpolate(ctx_r1.previewError); 797 } 798} 799function RfpDocumentsComponent_div_4_div_12_Template(rf, ctx) { 800 if (rf & 1) { 801 \u0275\u0275elementStart(0, "div", 134); 802 \u0275\u0275element(1, "div", 135); 803 \u0275\u0275elementEnd(); 804 } 805 if (rf & 2) { 806 const ctx_r1 = \u0275\u0275nextContext(2); 807 \u0275\u0275advance(); 808 \u0275\u0275property("innerHTML", ctx_r1.previewFile.htmlContent, \u0275\u0275sanitizeHtml); 809 } 810} 811function RfpDocumentsComponent_div_4_div_13_Template(rf, ctx) { 812 if (rf & 1) { 813 \u0275\u0275elementStart(0, "div", 136); 814 \u0275\u0275element(1, "ejs-documenteditor", 137, 3); 815 \u0275\u0275elementEnd(); 816 } 817 if (rf & 2) { 818 \u0275\u0275advance(); 819 \u0275\u0275property("isReadOnly", true)("enableSelection", true)("height", "100%")("width", "100%"); 820 } 821} 822function RfpDocumentsComponent_div_4_embed_14_Template(rf, ctx) { 823 if (rf & 1) { 824 \u0275\u0275element(0, "embed", 138); 825 } 826 if (rf & 2) { 827 const ctx_r1 = \u0275\u0275nextContext(2); 828 \u0275\u0275property("src", ctx_r1.previewFile.url, \u0275\u0275sanitizeResourceUrl); 829 } 830} 831function RfpDocumentsComponent_div_4_iframe_15_Template(rf, ctx) { 832 if (rf & 1) { 833 \u0275\u0275element(0, "iframe", 139); 834 } 835 if (rf & 2) { 836 const ctx_r1 = \u0275\u0275nextContext(2); 837 \u0275\u0275property("src", ctx_r1.previewFile.url, \u0275\u0275sanitizeResourceUrl); 838 } 839} 840function RfpDocumentsComponent_div_4_div_16_Template(rf, ctx) { 841 if (rf & 1) { 842 \u0275\u0275elementStart(0, "div", 140); 843 \u0275\u0275element(1, "i", 10); 844 \u0275\u0275text(2, " Loading..."); 845 \u0275\u0275elementEnd(); 846 } 847} 848function RfpDocumentsComponent_div_4_Template(rf, ctx) { 849 if (rf & 1) { 850 const _r19 = \u0275\u0275getCurrentView(); 851 \u0275\u0275elementStart(0, "div", 117); 852 \u0275\u0275listener("click", function RfpDocumentsComponent_div_4_Template_div_click_0_listener() { 853 \u0275\u0275restoreView(_r19); 854 const ctx_r1 = \u0275\u0275nextContext(); 855 return \u0275\u0275resetView(ctx_r1.closePreview()); 856 }); 857 \u0275\u0275elementStart(1, "div", 118); 858 \u0275\u0275listener("click", function RfpDocumentsComponent_div_4_Template_div_click_1_listener($event) { 859 \u0275\u0275restoreView(_r19); 860 return \u0275\u0275resetView($event.stopPropagation()); 861 }); 862 \u0275\u0275elementStart(2, "div", 119)(3, "h3", 120); 863 \u0275\u0275text(4); 864 \u0275\u0275elementEnd(); 865 \u0275\u0275elementStart(5, "div", 121)(6, "button", 122); 866 \u0275\u0275listener("click", function RfpDocumentsComponent_div_4_Template_button_click_6_listener() { 867 \u0275\u0275restoreView(_r19); 868 const ctx_r1 = \u0275\u0275nextContext();
869 return \u0275\u0275resetView(ctx_r1.downloadPreviewFile()); 870 }); 871 \u0275\u0275element(7, "i", 96); 872 \u0275\u0275elementEnd(); 873 \u0275\u0275elementStart(8, "button", 123); 874 \u0275\u0275listener("click", function RfpDocumentsComponent_div_4_Template_button_click_8_listener() { 875 \u0275\u0275restoreView(_r19); 876 const ctx_r1 = \u0275\u0275nextContext(); 877 return \u0275\u0275resetView(ctx_r1.closePreview()); 878 }); 879 \u0275\u0275text(9, "\xD7"); 880 \u0275\u0275elementEnd()()(); 881 \u0275\u0275elementStart(10, "div", 124); 882 \u0275\u0275template(11, RfpDocumentsComponent_div_4_div_11_Template, 7, 1, "div", 125)(12, RfpDocumentsComponent_div_4_div_12_Template, 2, 1, "div", 126)(13, RfpDocumentsComponent_div_4_div_13_Template, 3, 4, "div", 127)(14, RfpDocumentsComponent_div_4_embed_14_Template, 1, 1, "embed", 128)(15, RfpDocumentsComponent_div_4_iframe_15_Template, 1, 1, "iframe", 129)(16, RfpDocumentsComponent_div_4_div_16_Template, 3, 0, "div", 130); 883 \u0275\u0275elementEnd()()(); 884 } 885 if (rf & 2) { 886 const ctx_r1 = \u0275\u0275nextContext(); 887 \u0275\u0275advance(4); 888 \u0275\u0275textInterpolate(ctx_r1.previewFile.name); 889 \u0275\u0275advance(7); 890 \u0275\u0275property("ngIf", ctx_r1.previewError); 891 \u0275\u0275advance(); 892 \u0275\u0275property("ngIf", !ctx_r1.previewError && ctx_r1.previewFile.htmlContent); 893 \u0275\u0275advance(); 894 \u0275\u0275property("ngIf", !ctx_r1.previewError && !ctx_r1.previewFile.htmlContent && (ctx_r1.previewFile.type === "docx" || ctx_r1.previewFile.type === "doc")); 895 \u0275\u0275advance(); 896 \u0275\u0275property("ngIf", !ctx_r1.previewError && !ctx_r1.previewFile.htmlContent && ctx_r1.previewFile.url && ctx_r1.previewFile.type === "application/pdf"); 897 \u0275\u0275advance(); 898 \u0275\u0275property("ngIf", !ctx_r1.previewError && !ctx_r1.previewFile.htmlContent && ctx_r1.previewFile.url && ctx_r1.previewFile.type !== "application/pdf" && ctx_r1.previewFile.type !== "docx" && ctx_r1.previewFile.type !== "doc"); 899 \u0275\u0275advance(); 900 \u0275\u0275property("ngIf", ctx_r1.loadingFile && !ctx_r1.previewError); 901 } 902} 903var RfpDocumentsComponent = class _RfpDocumentsComponent { 904 router; 905 route; 906 rfpService; 907 sanitizer; 908 http; 909 location; 910 rfpId = ""; 911 source = 2; 912 // Default to RFP_MART (2) 913 rfpTitle = ""; 914 rfpDbId = ""; 915 files = []; 916 filteredFiles = []; 917 loading = true; 918 error = null; 919 isList = true; 920 isGrid = false; 921 selectedFile = null; 922 previewFile = null; 923 queryParamsSubscription; 924 _loadingFile = false; 925 get loadingFile() { 926 return this._loadingFile; 927 } 928 set loadingFile(val) { 929 this._loadingFile = val; 930 if (!val) { 931 this.isDownloadingFile = false; 932 this.isOpeningFile = false; 933 } 934 } 935 isDownloadingFile = false; 936 isOpeningFile = false; 937 isDownloadingAll = false; 938 previewError = null; 939 searchTerm = ""; 940 selectedType = "All"; 941 availableTypes = ["All", "PDF", "DOCX", "DOC", "RTF", "CSV", "XLSX", "XLS", "TXT", "XML", "ZIP"]; 942 activeDropdown = null; 943 activeTab = "initial"; 944 amendments = []; 945 loadingAmendments = false; 946 amendmentsError = null; 947 hasFetchedAmendments = false; 948 docEditorElement = null; 949 pendingSfdt = null; 950 set documentEditor(editor) { 951 if (editor) { 952 this.docEditorElement = editor; 953 if (this.pendingSfdt) { 954 const sfdtToLoad = this.pendingSfdt; 955 this.pendingSfdt = null; 956 setTimeout(() => { 957 try { 958 editor.open(sfdtToLoad); 959 } catch (e) { 960 console.error("Error loading SFDT in preview:", e); 961 } 962 }, 100); 963 } 964 } else { 965 this.docEditorElement = null; 966 } 967 } 968 get isSled2() { 969 return this.source === 1 || this.source === 2 || this.source === 3 || this.source === 5; 970 } 971 constructor(router, route, rfpService, sanitizer, http, location) { 972 this.router = router; 973 this.route = route; 974 this.rfpService = rfpService; 975 this.sanitizer = sanitizer; 976 this.http = http; 977 this.location = location; 978 } 979 ngOnInit() { 980 const state = history.state; 981 if (state && state.rfp_id) { 982 this.rfpId = state.rfp_id; 983 this.source = state.source ?? 2; 984 this.rfpTitle = state.rfpTitle ?? ""; 985 this.rfpDbId = state.rfpDbId ?? ""; 986 sessionStorage.setItem("rfp_doc_rfpId", this.rfpId); 987 sessionStorage.setItem("rfp_doc_source", String(this.source)); 988 sessionStorage.setItem("rfp_doc_rfpTitle", this.rfpTitle); 989 sessionStorage.setItem("rfp_doc_rfpDbId", this.rfpDbId); 990 } else { 991 this.queryParamsSubscription = this.route.queryParams.subscribe((params) => { 992 this.rfpId = params["rfp_id"] || sessionStorage.getItem("rfp_doc_rfpId") || ""; 993 this.source = params["source"] ? Number(params["source"]) : Number(sessionStorage.getItem("rfp_doc_source") || "2"); 994 this.rfpTitle = params["rfpTitle"] || sessionStorage.getItem("rfp_doc_rfpTitle") || ""; 995 this.rfpDbId = params["rfpDbId"] || sessionStorage.getItem("rfp_doc_rfpDbId") || ""; 996 }); 997 } 998 if (!this.rfpId) { 999 this.rfpId = sessionStorage.getItem("rfp_doc_rfpId") || ""; 1000 this.source = Number(sessionStorage.getItem("rfp_doc_source") || "2"); 1001 this.rfpTitle = sessionStorage.getItem("rfp_doc_rfpTitle") || ""; 1002 this.rfpDbId = sessionStorage.getItem("rfp_doc_rfpDbId") || ""; 1003 } 1004 if (this.rfpId) { 1005 this.fetchDocuments(); 1006 } else { 1007 this.loading = false;
1008 this.error = "No RFP details provided. Please go back to Overview and click the Documents card."; 1009 } 1010 } 1011 fetchDocuments() { 1012 this.loading = true; 1013 this.error = null; 1014 this.selectedFile = null; 1015 { 1016 const sourceStr = this.getSourceString(this.source); 1017 const targetId = this.rfpDbId || this.rfpId; 1018 this.rfpService.getRfpMartById(targetId, sourceStr).subscribe({ 1019 next: (res) => { 1020 let initialDocs = []; 1021 let amendmentDocs = []; 1022 if (res) { 1023 if (res.documents) { 1024 if (res.documents.initial && Array.isArray(res.documents.initial)) { 1025 initialDocs = res.documents.initial; 1026 } else if (res.result?.documents?.initial && Array.isArray(res.result.documents.initial)) { 1027 initialDocs = res.result.documents.initial; 1028 } else if (res.result?.data?.documents?.initial && Array.isArray(res.result.data.documents.initial)) { 1029 initialDocs = res.result.data.documents.initial; 1030 } 1031 if (res.documents.amendments && Array.isArray(res.documents.amendments)) { 1032 amendmentDocs = res.documents.amendments; 1033 } else if (res.result?.documents?.amendments && Array.isArray(res.result.documents.amendments)) { 1034 amendmentDocs = res.result.documents.amendments; 1035 } else if (res.result?.data?.documents?.amendments && Array.isArray(res.result.data.documents.amendments)) { 1036 amendmentDocs = res.result.data.documents.amendments; 1037 } 1038 } 1039 if (initialDocs.length === 0 && amendmentDocs.length === 0) { 1040 const flatDocs = res.documents || res.result?.documents || res.result?.data?.documents || []; 1041 if (Array.isArray(flatDocs)) { 1042 if (this.isSled2) { 1043 initialDocs = flatDocs.filter((d) => !this.isAmendmentFile(d)); 1044 amendmentDocs = flatDocs.filter((d) => this.isAmendmentFile(d)); 1045 } else { 1046 initialDocs = flatDocs; 1047 } 1048 } 1049 } 1050 } 1051 const rfpCreatedOn = this.source === 4 ? res?.createdOn || res?.created_on : void 0; 1052 this.files = initialDocs.map((doc) => this.mapDocument(doc, rfpCreatedOn)); 1053 this.amendments = amendmentDocs.map((doc) => this.mapDocument(doc, rfpCreatedOn)); 1054 this.hasFetchedAmendments = true; 1055 this.loading = false; 1056 this.filterFiles(); 1057 }, 1058 error: (err) => { 1059 console.error("Failed to load RFP details for documents from .NET API:", err); 1060 this.loading = false; 1061 this.error = "Failed to load RFP documents: " + (err.message || "Unknown error"); 1062 } 1063 }); 1064 } 1065 } 1066 mapDocument(doc, rfpCreatedOn) { 1067 const fileName = doc.fileName || doc.filename || doc.name || "Unnamed Document"; 1068 const ext = fileName.split(".").pop()?.toLowerCase() || "unknown"; 1069 const rawType = doc.fileType || ext; 1070 const displayType = typeof rawType === "string" && rawType.includes("/") ? ext : rawType; 1071 return { 1072 id: doc.id || doc.fileId || doc.ID, 1073 fileName, 1074 fileType: displayType, 1075 fileSize: doc.fileSizeBytes ? this.formatBytes(doc.fileSizeBytes) : doc.fileSize || doc.file_size || "N/A", 1076 uploadedDate: this.formatDate(doc.createdOn || doc.created_on || doc.created_at || doc.createdAt || doc.created_date || doc.uploaded_at || rfpCreatedOn), 1077 modified: doc.modified_date || doc.updated_at || doc.modifiedOn || "N/A", 1078 owner: doc.owner || "System", 1079 status: doc.status || "Approved", 1080 tags: doc.tags || [], 1081 blobUrl: doc.blobUrl, 1082 filePath: doc.filePath, 1083 sourceUrl: doc.sourceUrl 1084 }; 1085 } 1086 formatDate(value) { 1087 if (!value) 1088 return "N/A"; 1089 const normalized = typeof value === "string" ? value.replace(" ", "T") : value; 1090 const date = new Date(normalized); 1091 if (isNaN(date.getTime())) 1092 return "N/A"; 1093 return date.toLocaleDateString("en-US", { 1094 year: "numeric", 1095 month: "short", 1096 day: "numeric", 1097 hour: "2-digit", 1098 minute: "2-digit" 1099 }); 1100 } 1101 formatBytes(bytes, decimals = 2) { 1102 if (!bytes) 1103 return "0 Bytes";
1104 const k = 1024; 1105 const dm = decimals < 0 ? 0 : decimals; 1106 const sizes = ["Bytes", "KB", "MB", "GB", "TB"]; 1107 const i = Math.floor(Math.log(bytes) / Math.log(k)); 1108 return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; 1109 } 1110 fetchDocumentsFromListFiles() { 1111 this.loading = true; 1112 this.error = null; 1113 this.selectedFile = null; 1114 this.rfpService.getListFiles(this.rfpId, this.source).subscribe({ 1115 next: (res) => { 1116 this.loading = false; 1117 if (res && res.files) { 1118 const mapFile = (file) => { 1119 const ext = file.file_name?.split(".").pop()?.toLowerCase() || "unknown"; 1120 return { 1121 id: file.id, 1122 fileName: file.file_name, 1123 fileType: ext, 1124 fileSize: file.file_size || "N/A", 1125 uploadedDate: this.formatDate(file.created_at || file.createdAt || file.created_date || file.uploaded_at), 1126 modified: file.modified_date || file.updated_at || "N/A", 1127 owner: file.owner || "System", 1128 status: file.status || "Approved", 1129 tags: file.tags || [], 1130 documentType: file.document_type || "initial" 1131 }; 1132 }; 1133 if (Array.isArray(res.files)) { 1134 this.files = res.files.map((file) => mapFile(file)); 1135 this.amendments = []; 1136 this.hasFetchedAmendments = false; 1137 } else if (typeof res.files === "object") { 1138 const initialList = res.files.initial || []; 1139 const amendmentsList = res.files.amendments || []; 1140 this.files = initialList.map((file) => mapFile(file)); 1141 this.amendments = amendmentsList.map((file) => mapFile(file)); 1142 this.hasFetchedAmendments = true; 1143 } 1144 this.filterFiles(); 1145 } else { 1146 this.files = []; 1147 this.amendments = []; 1148 this.hasFetchedAmendments = false; 1149 this.filterFiles(); 1150 } 1151 }, 1152 error: (err) => { 1153 this.loading = false; 1154 this.error = "Failed to load RFP documents: " + (err.message || "Unknown error"); 1155 } 1156 }); 1157 } 1158 setActiveTab(tab) { 1159 this.activeTab = tab; 1160 this.selectedFile = null; 1161 this.previewFile = null; 1162 this.previewError = null; 1163 this.filterFiles(); 1164 } 1165 getSourceString(source) { 1166 if (source === 1) 1167 return "SAM.GOV"; 1168 if (source === 3) 1169 return "SLED 2"; 1170 if (source === 4) 1171 return "SELF"; 1172 if (source === 5) 1173 return "GRANTS_GOV"; 1174 return "SLED"; 1175 } 1176 isAmendmentFile(doc) { 1177 if (!doc) 1178 return false; 1179 if (doc.isAmendment === true || doc.isAmendment === "true" || doc.isAmendment === 1 || doc.isAmendment === "1") 1180 return true; 1181 if (doc.is_amendment === true || doc.is_amendment === "true" || doc.is_amendment === 1 || doc.is_amendment === "1") 1182 return true; 1183 if (doc.fileType?.toLowerCase() === "amendment" || doc.file_type?.toLowerCase() === "amendment") 1184 return true; 1185 if (doc.documentType?.toLowerCase() === "amendment" || doc.document_type?.toLowerCase() === "amendment") 1186 return true; 1187 if (doc.tags && Array.isArray(doc.tags) && doc.tags.some((t) => t.toLowerCase() === "amendment")) 1188 return true; 1189 const name = (doc.fileName || doc.filename || doc.name || "").toLowerCase(); 1190 if (name.includes("amendment") || name.includes("amend") || name.includes("addendum")) { 1191 return true; 1192 } 1193 return false; 1194 } 1195 filterFiles() { 1196 const sourceArray = this.activeTab === "amendments" ? this.amendments : this.files; 1197 let result = [...sourceArray]; 1198 if (this.searchTerm.trim()) { 1199 const search = this.searchTerm.toLowerCase(); 1200 result = result.filter((f) => f.fileName.toLowerCase().includes(search)); 1201 } 1202 if (this.selectedType !== "All") { 1203 const type = this.selectedType.toLowerCase(); 1204 result = result.filter((f) => f.fileType === type); 1205 } 1206 this.filteredFiles = result; 1207 } 1208 selectFile(file) { 1209 this.selectedFile = file; 1210 } 1211 closeFileDetails() { 1212 this.selectedFile = null; 1213 } 1214 gotoListView() { 1215 this.isList = true; 1216 this.isGrid = false;
1217 } 1218 gotoGridView() { 1219 this.isList = false; 1220 this.isGrid = true; 1221 } 1222 goToBack() { 1223 const targetId = this.rfpDbId || this.rfpId || sessionStorage.getItem("rfp_doc_rfpDbId") || sessionStorage.getItem("rfp_doc_rfpId"); 1224 const sourceNum = this.source || Number(sessionStorage.getItem("rfp_doc_source") || "2"); 1225 if (history.state && history.state.navigationId && history.state.navigationId > 1) { 1226 this.location.back(); 1227 } else if (targetId) { 1228 this.router.navigate([`/rfp/${targetId}/overview`], { 1229 state: { source: sourceNum } 1230 }); 1231 } else { 1232 this.router.navigate(["/"]); 1233 } 1234 } 1235 toggleDropdown(dropdown, event) { 1236 event.stopPropagation(); 1237 if (this.activeDropdown === dropdown) { 1238 this.activeDropdown = null; 1239 } else { 1240 this.activeDropdown = dropdown; 1241 } 1242 } 1243 closeDropdownOnOutsideClick() { 1244 this.activeDropdown = null; 1245 } 1246 selectFilter(type, value) { 1247 if (type === "type") { 1248 this.selectedType = value; 1249 } 1250 this.activeDropdown = null; 1251 this.filterFiles(); 1252 } 1253 resetFilters() { 1254 this.searchTerm = ""; 1255 this.selectedType = "All"; 1256 this.filterFiles(); 1257 } 1258 getFileIcon(fileType) { 1259 const t = (fileType || "").toUpperCase(); 1260 if (t === "PDF") 1261 return "file-text"; 1262 if (t === "DOC" || t === "DOCX") 1263 return "file-text"; 1264 if (t === "XLS" || t === "XLSX" || t === "CSV" || t.includes("SPREADSHEET")) 1265 return "file-text"; 1266 if (t === "PNG" || t === "JPG" || t === "JPEG" || t === "GIF") 1267 return "image"; 1268 if (t === "TXT" || t === "RTF") 1269 return "file-text"; 1270 if (t === "ZIP" || t === "RAR") 1271 return "upload-cloud"; 1272 return "file-text"; 1273 } 1274 getFileIconClass(fileType) { 1275 const t = (fileType || "").toUpperCase(); 1276 if (t === "PDF") 1277 return "icon-pdf"; 1278 if (t === "DOC" || t === "DOCX") 1279 return "icon-word"; 1280 if (t === "XLS" || t === "XLSX" || t === "CSV" || t.includes("SPREADSHEET")) 1281 return "icon-excel"; 1282 if (t === "PNG" || t === "JPG" || t === "JPEG" || t === "GIF") 1283 return "icon-image"; 1284 if (t === "TXT" || t === "RTF") 1285 return "icon-text"; 1286 if (t === "ZIP" || t === "RAR") 1287 return "icon-archive"; 1288 return "icon-generic"; 1289 } 1290 getMimeType(fileName) { 1291 const ext = fileName.toLowerCase().split(".").pop() || ""; 1292 const mimeTypes = { 1293 "pdf": "application/pdf", 1294 "doc": "application/msword", 1295 "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", 1296 "xls": "application/vnd.ms-excel", 1297 "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 1298 "csv": "text/csv", 1299 "rtf": "application/rtf", 1300 "txt": "text/plain", 1301 "html": "text/html", 1302 "htm": "text/html", 1303 "zip": "application/zip", 1304 "png": "image/png", 1305 "jpg": "image/jpeg", 1306 "jpeg": "image/jpeg" 1307 }; 1308 if (mimeTypes[ext]) 1309 return mimeTypes[ext]; 1310 if (fileName.toLowerCase().includes("spreadsheet")) { 1311 return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 1312 } 1313 return "application/octet-stream"; 1314 } 1315 escapeHtml(text) { 1316 const div = document.createElement("div"); 1317 div.textContent = text; 1318 return div.innerHTML; 1319 } 1320 formatAndHighlightXml(xml) { 1321 let formatted = ""; 1322 let indent = 0; 1323 const tab = " "; 1324 const cleanXml = xml.replace(/>\s*</g, "><").trim(); 1325 const tokens = cleanXml.split(/(<[^>]+>)/g).filter((t) => t.length > 0); 1326 for (const token of tokens) { 1327 if (token.startsWith("<?") || token.startsWith("<!")) { 1328 formatted += tab.repeat(indent) + token + "\n"; 1329 } else if (token.startsWith("</")) { 1330 indent = Math.max(0, indent - 1); 1331 formatted += tab.repeat(indent) + token + "\n"; 1332 } else if (token.startsWith("<") && !token.endsWith("/>") && !token.includes("</")) { 1333 formatted += tab.repeat(indent) + token + "\n"; 1334 indent++; 1335 } else if (token.startsWith("<") && token.endsWith("/>")) { 1336 formatted += tab.repeat(indent) + token + "\n"; 1337 } else { 1338 const textContent = token.trim(); 1339 if (textContent.length > 0) { 1340 formatted += tab.repeat(indent) + textContent + "\n"; 1341 } 1342 } 1343 } 1344 let escaped = this.escapeHtml(formatted.trim() || xml); 1345 return escaped.replace(/(<\/?[\w:.-]+)/g, '<span style="color: #0284c7; font-weight: 600;">$1</span>').replace(/([\w:.-]+)=("[^&]*"|'[^&]*')/g, '<span style="color: #b45309; font-weight: 500;">$1</span>=<span style="color: #15803d;">$2</span>').replace(/(>|\/>)/g, '<span style="color: #0284c7; font-weight: 600;">$1</span>').replace(/(<!--[\s\S]*?-->)/g, '<span style="color: #64748b; font-style: italic;">$1</span>').replace(/(<\?[\s\S]*?\?>)/g, '<span style="color: #7c3aed; font-style: italic;">$1</span>'); 1346 } 1347 downloadFolderFile(file) { 1348 if (!file.id) 1349 return; 1350 this.isDownloadingFile = true; 1351 this.loadingFile = true; 1352 const obs = this.rfpService.downloadListFile(this.rfpId, this.source, file.id); 1353 obs.subscribe({ 1354 next: (res) => { 1355 this.loadingFile = false;
1356 this.isDownloadingFile = false; 1357 const blob = res.body; 1358 if (blob) { 1359 const url = URL.createObjectURL(blob); 1360 this.downloadFileDirectly(file.fileName, url); 1361 } else { 1362 alert("Could not download file: Empty response body."); 1363 } 1364 }, 1365 error: (err) => { 1366 this.loadingFile = false; 1367 this.isDownloadingFile = false; 1368 console.error("Failed to download file:", err); 1369 alert("Failed to download file. Please try again."); 1370 } 1371 }); 1372 } 1373 previewFolderFile(file) { 1374 if (!file.id) { 1375 alert("File ID not available"); 1376 return; 1377 } 1378 this.isOpeningFile = true; 1379 this.loadingFile = true; 1380 this.previewError = null; 1381 const obs = this.rfpService.downloadListFile(this.rfpId, this.source, file.id); 1382 obs.subscribe({ 1383 next: (res) => { 1384 const blob = res.body; 1385 if (!blob) { 1386 this.previewError = "Empty file response received from server."; 1387 this.loadingFile = false; 1388 return; 1389 } 1390 const fileName = file.fileName || "preview"; 1391 const headerSlice = blob.slice(0, 8192); 1392 const reader = new FileReader(); 1393 reader.onloadend = () => { 1394 const arr = new Uint8Array(reader.result); 1395 const isPdfMagic = arr.length >= 4 && arr[0] === 37 && // '%' 1396 arr[1] === 80 && // 'P' 1397 arr[2] === 68 && // 'D' 1398 arr[3] === 70; 1399 const fileExt = fileName.toLowerCase().split(".").pop() || ""; 1400 const isZipMagic = arr.length >= 2 && arr[0] === 80 && arr[1] === 75; 1401 const isXlsMagic = arr.length >= 4 && arr[0] === 208 && arr[1] === 207 && arr[2] === 17 && arr[3] === 224; 1402 let isOpenXmlExcel = false; 1403 let isOpenXmlWord = false; 1404 if (isZipMagic) { 1405 const latinText = new TextDecoder("latin1").decode(arr); 1406 isOpenXmlExcel = latinText.includes("xl/"); 1407 isOpenXmlWord = latinText.includes("word/"); 1408 } 1409 const isPdf = isPdfMagic || !isZipMagic && !isXlsMagic && (fileExt === "pdf" || fileName.toLowerCase().endsWith(".pdf")); 1410 const isSpreadsheet = isOpenXmlExcel || fileExt === "xlsx" || fileExt === "xls" || fileName.toLowerCase().includes("spreadsheet") || file.fileType && file.fileType.toLowerCase().includes("spreadsheet") || (isZipMagic || isXlsMagic) && (fileName.toLowerCase().includes("spreadsheet") || file.fileType && file.fileType.toLowerCase().includes("spreadsheet")); 1411 let currentExt = isPdf ? "pdf" : fileExt; 1412 if (!isPdf && isSpreadsheet) { 1413 currentExt = "xlsx"; 1414 } else if (!isPdf && (isOpenXmlWord || isZipMagic) && (currentExt === "pdf" || !currentExt)) { 1415 currentExt = "docx"; 1416 } 1417 const mimeType = isPdf ? "application/pdf" : isSpreadsheet ? "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" : currentExt === "docx" ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : this.getMimeType(fileName); 1418 const typedBlob = new Blob([blob], { type: mimeType }); 1419 const url = URL.createObjectURL(typedBlob); 1420 if (currentExt === "pdf") { 1421 const pdfUrl = url + "#toolbar=1&navpanes=0&messages=0"; 1422 const safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(pdfUrl); 1423 this.previewFile = { 1424 name: fileName, 1425 url: safeUrl, 1426 type: "application/pdf", 1427 blobUrl: url, 1428 rawFile: file 1429 }; 1430 this.loadingFile = false; 1431 } else if (["png", "jpg", "jpeg", "gif", "svg", "webp", "bmp"].includes(currentExt)) { 1432 const htmlContent = ` 1433 <div class="image-preview-wrapper" style="text-align: center; padding: 24px; background: #f8fafc; border-radius: 8px;"> 1434 <img src="${url}" alt="${this.escapeHtml(fileName)}" style="max-height: 75vh; max-width: 100%; object-fit: contain; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); display: inline-block;" /> 1435 </div> 1436 `; 1437 const safeHtml = this.sanitizer.bypassSecurityTrustHtml(htmlContent); 1438 this.previewFile = { 1439 name: fileName, 1440 url: this.sanitizer.bypassSecurityTrustResourceUrl(url), 1441 type: `image/${currentExt}`, 1442 htmlContent: safeHtml, 1443 blobUrl: url,
1444 rawFile: file 1445 }; 1446 this.loadingFile = false; 1447 } else if (isSpreadsheet) { 1448 typedBlob.arrayBuffer().then((arrayBuffer) => { 1449 try { 1450 const workbook = readSync(arrayBuffer, { type: "array" }); 1451 const firstSheetName = workbook.SheetNames[0]; 1452 const worksheet = workbook.Sheets[firstSheetName]; 1453 const html = utils.sheet_to_html(worksheet); 1454 let fullHtml = ` 1455 <div class="xlsx-preview-wrapper" style="font-family: 'Lexend', Arial, sans-serif; padding: 20px; background: white; text-align: left;"> 1456 <style> 1457 .xlsx-preview-wrapper { 1458 font-family: 'Lexend', Arial, sans-serif; 1459 } 1460 .xlsx-preview-wrapper .sheet-info { 1461 font-size: 12px; 1462 color: #666; 1463 margin: 10px 0; 1464 font-style: italic; 1465 } 1466 .xlsx-preview-wrapper .sheet-content { 1467 overflow: auto; 1468 max-width: 100%; 1469 } 1470 .xlsx-preview-wrapper table { 1471 border-collapse: collapse; 1472 width: 100%; 1473 font-size: 12px; 1474 background: white; 1475 } 1476 .xlsx-preview-wrapper td, .xlsx-preview-wrapper th { 1477 border: 1px solid #ddd; 1478 padding: 8px 12px; 1479 text-align: left; 1480 min-width: 80px; 1481 } 1482 .xlsx-preview-wrapper th { 1483 background-color: #f2f2f2; 1484 font-weight: bold; 1485 position: sticky; 1486 top: 0; 1487 z-index: 1; 1488 } 1489 .xlsx-preview-wrapper tr:nth-child(even) { 1490 background-color: #f9f9f9; 1491 } 1492 .xlsx-preview-wrapper tr:hover { 1493 background-color: #f5f5f5; 1494 } 1495 </style> 1496 `; 1497 if (workbook.SheetNames.length > 1) { 1498 fullHtml += `<p class="sheet-info">Showing sheet 1 of ${workbook.SheetNames.length}</p>`; 1499 } 1500 fullHtml += `<div class="sheet-content">${html}</div></div>`; 1501 const safeHtml = this.sanitizer.bypassSecurityTrustHtml(fullHtml); 1502 this.previewFile = { 1503 name: fileName, 1504 url: this.sanitizer.bypassSecurityTrustResourceUrl(url), 1505 type: "xlsx", 1506 htmlContent: safeHtml, 1507 blobUrl: url, 1508 rawFile: file 1509 }; 1510 this.loadingFile = false; 1511 } catch (error) { 1512 console.error("Error rendering Spreadsheet:", error); 1513 this.downloadFileDirectly(fileName, url); 1514 this.loadingFile = false; 1515 } 1516 }).catch((err) => { 1517 console.error("Error reading Spreadsheet arrayBuffer:", err); 1518 this.downloadFileDirectly(fileName, url); 1519 this.loadingFile = false; 1520 }); 1521 } else if (currentExt === "docx" || currentExt === "doc") { 1522 const uploadName = currentExt === "docx" && !fileName.toLowerCase().endsWith(".docx") && !fileName.toLowerCase().endsWith(".doc") ? `${fileName.replace(/\.[^/.]+$/, "")}.docx` : fileName; 1523 const tempFile = new File([typedBlob], uploadName, { type: mimeType }); 1524 const formData = new FormData(); 1525 formData.append("file", tempFile); 1526 const importUrl = getDocumentEditorImportURL(); 1527 this.http.post(importUrl, formData, { responseType: "text" }).subscribe({ 1528 next: (sfdt) => { 1529 this.pendingSfdt = sfdt; 1530 this.previewFile = { 1531 name: fileName, 1532 url: this.sanitizer.bypassSecurityTrustResourceUrl(url), 1533 type: currentExt, 1534 blobUrl: url,
1535 rawFile: file 1536 }; 1537 this.loadingFile = false; 1538 if (this.docEditorElement) { 1539 try { 1540 this.docEditorElement.open(sfdt); 1541 this.pendingSfdt = null; 1542 } catch (e) { 1543 console.error("Error loading SFDT directly:", e); 1544 } 1545 } 1546 }, 1547 error: (err) => { 1548 console.error("Failed to convert DOC/DOCX to SFDT:", err); 1549 if (currentExt === "docx") { 1550 this.fallbackToMammoth(typedBlob, fileName, url, mimeType, file); 1551 } else { 1552 this.downloadFileDirectly(fileName, url); 1553 this.loadingFile = false; 1554 } 1555 } 1556 }); 1557 } else if (currentExt === "rtf") { 1558 typedBlob.text().then((text) => { 1559 const plainText = text.replace(/\\[a-z]+\d*\s?/g, "").replace(/[{}]/g, "").replace(/\\/g, "").trim(); 1560 const htmlContent = ` 1561 <div class="rtf-preview"> 1562 <style> 1563 .rtf-preview { 1564 font-family: 'Lexend', monospace; 1565 font-size: 12pt; 1566 line-height: 1.6; 1567 color: #000000; 1568 max-width: 8.5in; 1569 margin: 0 auto; 1570 padding: 1in; 1571 background: white; 1572 white-space: pre-wrap; 1573 word-wrap: break-word; 1574 } 1575 </style> 1576 ${plainText.replace(/\n/g, "<br>")} 1577 </div> 1578 `; 1579 const safeHtml = this.sanitizer.bypassSecurityTrustHtml(htmlContent); 1580 const safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url); 1581 this.previewFile = { 1582 name: fileName, 1583 url: safeUrl, 1584 type: "text/rtf", 1585 htmlContent: safeHtml, 1586 blobUrl: url, 1587 rawFile: file 1588 }; 1589 this.loadingFile = false; 1590 }).catch((error) => { 1591 console.error("Error converting RTF:", error); 1592 this.downloadFileDirectly(fileName, url); 1593 this.loadingFile = false; 1594 }); 1595 } else if (currentExt === "csv") { 1596 typedBlob.text().then((text) => { 1597 const lines = text.split("\n").filter((line) => line.trim()); 1598 if (lines.length === 0) { 1599 throw new Error("CSV file is empty"); 1600 } 1601 const rows = lines.map((line) => { 1602 const cells = []; 1603 let cell = ""; 1604 let inQuotes = false; 1605 for (let i = 0; i < line.length; i++) { 1606 const char = line[i]; 1607 if (char === '"') { 1608 inQuotes = !inQuotes; 1609 } else if (char === "," && !inQuotes) { 1610 cells.push(cell.trim()); 1611 cell = ""; 1612 } else { 1613 cell += char; 1614 } 1615 } 1616 cells.push(cell.trim()); 1617 return cells; 1618 }); 1619 const headers = rows[0]; 1620 const dataRows = rows.slice(1); 1621 const tableHtml = ` 1622 <div class="csv-preview"> 1623 <style> 1624 .csv-preview { 1625 font-family: 'Lexend'; 1626 font-size: 11pt; 1627 max-width: 100%; 1628 margin: 0 auto; 1629 padding: 20px; 1630 background: white; 1631 overflow-x: auto; 1632 } 1633 .csv-preview table { 1634 border-collapse: collapse; 1635 width: 100%; 1636 margin: 0; 1637 border: 1px solid #ddd; 1638 } 1639 .csv-preview th { 1640 background: #f0f0f0; 1641 font-weight: bold; 1642 padding: 10px; 1643 border: 1px solid #ddd; 1644 text-align: left; 1645 position: sticky; 1646 top: 0; 1647 z-index: 1; 1648 } 1649 .csv-preview td { 1650 padding: 8px 10px; 1651 border: 1px solid #ddd; 1652 white-space: nowrap; 1653 } 1654 .csv-preview tr:nth-child(even) { 1655 background: #f9f9f9; 1656 } 1657 .csv-preview tr:hover { 1658 background: #f0f0f0; 1659 } 1660 </style> 1661 <table> 1662 <thead> 1663 <tr> 1664 ${headers.map((h) => `<th>${this.escapeHtml(h)}</th>`).join("")} 1665 </tr> 1666 </thead> 1667 <tbody> 1668 ${dataRows.map((row) => ` 1669 <tr> 1670 ${row.map((cell) => `<td>${this.escapeHtml(cell)}</td>`).join("")} 1671 </tr> 1672 `).join("")} 1673 </tbody> 1674 </table> 1675 </div> 1676 `; 1677 const safeHtml = this.sanitizer.bypassSecurityTrustHtml(tableHtml); 1678 const safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url); 1679 this.previewFile = { 1680 name: fileName, 1681 url: safeUrl, 1682 type: "text/csv", 1683 htmlContent: safeHtml, 1684 blobUrl: url,
1685 rawFile: file 1686 }; 1687 this.loadingFile = false; 1688 }).catch((error) => { 1689 console.error("Error converting CSV:", error); 1690 this.downloadFileDirectly(fileName, url); 1691 this.loadingFile = false; 1692 }); 1693 } else if (currentExt === "html" || currentExt === "htm") { 1694 this.previewFile = { 1695 name: fileName, 1696 url: this.sanitizer.bypassSecurityTrustResourceUrl(url), 1697 type: "text/html", 1698 blobUrl: url, 1699 rawFile: file 1700 }; 1701 this.loadingFile = false; 1702 } else if (currentExt === "xml") { 1703 typedBlob.text().then((text) => { 1704 const highlighted = this.formatAndHighlightXml(text); 1705 const htmlContent = ` 1706 <div class="xml-preview-content" style="font-family: 'Consolas', 'Fira Code', 'Monaco', monospace; font-size: 12.5px; line-height: 1.65; color: #1e293b; white-space: pre-wrap; word-wrap: break-word;"> 1707 <code>${highlighted}</code> 1708 </div> 1709 `; 1710 const safeHtml = this.sanitizer.bypassSecurityTrustHtml(htmlContent); 1711 this.previewFile = { 1712 name: fileName, 1713 url: this.sanitizer.bypassSecurityTrustResourceUrl(url), 1714 type: "application/xml", 1715 htmlContent: safeHtml, 1716 blobUrl: url, 1717 rawFile: file 1718 }; 1719 this.loadingFile = false; 1720 }).catch((error) => { 1721 console.error("Error reading XML file:", error); 1722 this.downloadFileDirectly(fileName, url); 1723 this.loadingFile = false; 1724 }); 1725 } else if (currentExt === "txt") { 1726 window.open(url, "_blank"); 1727 setTimeout(() => { 1728 URL.revokeObjectURL(url); 1729 }, 1e3); 1730 this.loadingFile = false; 1731 } else { 1732 this.downloadFileDirectly(fileName, url); 1733 this.loadingFile = false; 1734 } 1735 }; 1736 reader.readAsArrayBuffer(headerSlice); 1737 }, 1738 error: (error) => { 1739 console.error("Error previewing file:", error); 1740 this.previewError = "Failed to load file preview. Please try again."; 1741 this.loadingFile = false; 1742 } 1743 }); 1744 } 1745 downloadAllFiles() { 1746 return __async(this, null, function* () { 1747 const docs = (this.activeTab === "amendments" ? this.amendments : this.files).filter((f) => f.id); 1748 if (!docs.length || this.isDownloadingAll) 1749 return; 1750 this.isDownloadingAll = true; 1751 try { 1752 const results = yield Promise.all(docs.map((file) => __async(this, null, function* () { 1753 try { 1754 const res = yield firstValueFrom(this.rfpService.downloadListFile(this.rfpId, this.source, file.id)); 1755 return res.body ? { fileName: file.fileName, blob: res.body } : null; 1756 } catch (err) { 1757 console.error(`Failed to download ${file.fileName}:`, err); 1758 return null; 1759 } 1760 }))); 1761 const downloaded = results.filter((r) => !!r); 1762 if (!downloaded.length) { 1763 alert("Failed to download files. Please try again."); 1764 return; 1765 } 1766 const zip = new import_jszip.default(); 1767 const usedNames = /* @__PURE__ */ new Set(); 1768 for (const { fileName, blob } of downloaded) { 1769 let name = fileName; 1770 let counter = 1; 1771 while (usedNames.has(name)) { 1772 const dotIdx = fileName.lastIndexOf("."); 1773 name = dotIdx > 0 ? `${fileName.slice(0, dotIdx)} (${counter})${fileName.slice(dotIdx)}` : `${fileName} (${counter})`; 1774 counter++; 1775 } 1776 usedNames.add(name); 1777 zip.file(name, blob); 1778 } 1779 const zipBlob = yield zip.generateAsync({ type: "blob" }); 1780 const zipName = this.activeTab === "amendments" ? "RFP-Amendments.zip" : "RFP-Package.zip"; 1781 this.downloadFileDirectly(zipName, URL.createObjectURL(zipBlob)); 1782 if (downloaded.length < docs.length) { 1783 alert(`${docs.length - downloaded.length} file(s) could not be downloaded and were skipped.`); 1784 } 1785 } finally { 1786 this.isDownloadingAll = false;
1787 } 1788 }); 1789 } 1790 downloadFileDirectly(fileName, url) { 1791 const link = document.createElement("a"); 1792 link.href = url; 1793 link.download = fileName; 1794 document.body.appendChild(link); 1795 link.click(); 1796 document.body.removeChild(link); 1797 URL.revokeObjectURL(url); 1798 } 1799 fallbackToMammoth(blob, fileName, url, mimeType, rawFile) { 1800 blob.arrayBuffer().then((arrayBuffer) => __async(this, null, function* () { 1801 try { 1802 const result = yield mammoth.convertToHtml({ arrayBuffer }, { 1803 styleMap: [ 1804 "p[style-name='Heading 1'] => h1:fresh", 1805 "p[style-name='Heading 2'] => h2:fresh", 1806 "p[style-name='Heading 3'] => h3:fresh", 1807 "p[style-name='Heading 4'] => h4:fresh", 1808 "p[style-name='Heading 5'] => h5:fresh", 1809 "p[style-name='Heading 6'] => h6:fresh", 1810 "p[style-name='Title'] => h1.title:fresh", 1811 "p[style-name='Subtitle'] => h2.subtitle:fresh" 1812 ], 1813 includeDefaultStyleMap: true 1814 }); 1815 const wrappedHtml = `
1816 <div class="docx-preview"> 1817 <style> 1818 .docx-preview { 1819 font-family: 'Lexend'; 1820 font-size: 12pt; 1821 line-height: 1.5; 1822 color: #000000; 1823 max-width: 8.5in; 1824 margin: 0 auto; 1825 padding: 1in; 1826 background: white; 1827 word-wrap: break-word; 1828 } 1829 .docx-preview * { 1830 box-sizing: border-box; 1831 } 1832 .docx-preview p { 1833 margin: 0 0 12pt 0; 1834 text-align: left; 1835 word-wrap: break-word; 1836 display: block; 1837 } 1838 .docx-preview p:empty { 1839 height: 12pt; 1840 margin: 0 0 12pt 0; 1841 } 1842 .docx-preview p:last-child { 1843 margin-bottom: 0; 1844 } 1845 .docx-preview h1, .docx-preview h2, .docx-preview h3, 1846 .docx-preview h4, .docx-preview h5, .docx-preview h6 { 1847 margin-top: 12pt; 1848 margin-bottom: 6pt; 1849 font-weight: bold; 1850 page-break-after: avoid; 1851 } 1852 .docx-preview h1 { font-size: 16pt; } 1853 .docx-preview h2 { font-size: 14pt; } 1854 .docx-preview h3 { font-size: 13pt; } 1855 .docx-preview h4 { font-size: 12pt; } 1856 .docx-preview ul, .docx-preview ol { 1857 margin: 0 0 12pt 0; 1858 padding-left: 36pt; 1859 } 1860 .docx-preview li { 1861 margin-bottom: 6pt; 1862 display: list-item; 1863 } 1864 .docx-preview table { 1865 border-collapse: collapse; 1866 width: 100%; 1867 margin: 12pt 0; 1868 border: 1px solid #000; 1869 } 1870 .docx-preview table td, .docx-preview table th { 1871 border: 1px solid #000; 1872 padding: 6pt; 1873 vertical-align: top; 1874 } 1875 .docx-preview strong, .docx-preview b { 1876 font-weight: bold; 1877 } 1878 .docx-preview em, .docx-preview i { 1879 font-style: italic; 1880 } 1881 .docx-preview u { 1882 text-decoration: underline; 1883 } 1884 .docx-preview br { 1885 display: block; 1886 content: ""; 1887 margin-top: 0; 1888 } 1889 .docx-preview div { 1890 margin: 0; 1891 padding: 0; 1892 } 1893 </style> 1894 \${result.value} 1895 </div> 1896 `; 1897 const safeHtml = this.sanitizer.bypassSecurityTrustHtml(wrappedHtml); 1898 this.previewFile = { 1899 name: fileName, 1900 url: this.sanitizer.bypassSecurityTrustResourceUrl(url), 1901 type: mimeType, 1902 htmlContent: safeHtml, 1903 blobUrl: url, 1904 rawFile 1905 }; 1906 this.loadingFile = false; 1907 } catch (error) { 1908 console.error("Error converting DOCX with Mammoth:", error); 1909 this.downloadFileDirectly(fileName, url); 1910 this.loadingFile = false; 1911 } 1912 })); 1913 } 1914 closePreview() { 1915 if (this.previewFile?.url) { 1916 const url = this.previewFile.url.changingThisBreaksApplicationSecurity; 1917 if (url && url.startsWith("blob:")) { 1918 URL.revokeObjectURL(url); 1919 } 1920 if (this.previewFile.blobUrl && this.previewFile.blobUrl !== url && this.previewFile.blobUrl.startsWith("blob:")) { 1921 URL.revokeObjectURL(this.previewFile.blobUrl); 1922 } 1923 } 1924 this.previewFile = null; 1925 this.previewError = null; 1926 this.docEditorElement = null; 1927 this.pendingSfdt = null; 1928 } 1929 ngOnDestroy() { 1930 if (this.queryParamsSubscription) { 1931 this.queryParamsSubscription.unsubscribe(); 1932 } 1933 this.closePreview(); 1934 } 1935 downloadPreviewFile() { 1936 if (this.previewFile) { 1937 if (this.previewFile.blobUrl) { 1938 const link = document.createElement("a"); 1939 link.href = this.previewFile.blobUrl; 1940 link.download = this.previewFile.name; 1941 document.body.appendChild(link); 1942 link.click(); 1943 document.body.removeChild(link); 1944 } else if (this.previewFile.rawFile) { 1945 this.downloadFolderFile(this.previewFile.rawFile); 1946 } 1947 } 1948 } 1949 static \u0275fac = function RfpDocumentsComponent_Factory(__ngFactoryType__) { 1950 return new (__ngFactoryType__ || _RfpDocumentsComponent)(\u0275\u0275directiveInject(Router), \u0275\u0275directiveInject(ActivatedRoute), \u0275\u0275directiveInject(RfpService), \u0275\u0275directiveInject(DomSanitizer), \u0275\u0275directiveInject(HttpClient), \u0275\u0275directiveInject(Location)); 1951 }; 1952 static \u0275cmp = /* @__PURE__ */ \u0275\u0275defineComponent({ type: _RfpDocumentsComponent, selectors: [["app-rfp-documents"]], viewQuery: function RfpDocumentsComponent_Query(rf, ctx) { 1953 if (rf & 1) { 1954 \u0275\u0275viewQuery(_c0, 5); 1955 } 1956 if (rf & 2) { 1957 let _t; 1958 \u0275\u0275queryRefresh(_t = \u0275\u0275loadQuery()) && (ctx.documentEditor = _t.first); 1959 } 1960 }, hostBindings: function RfpDocumentsComponent_HostBindings(rf, ctx) { 1961 if (rf & 1) { 1962 \u0275\u0275listener("click", function RfpDocumentsComponent_click_HostBindingHandler() { 1963 return ctx.closeDropdownOnOutsideClick(); 1964 }, false, \u0275\u0275resolveDocument); 1965 } 1966 }, decls: 5, vars: 4, consts: [["standardBreadcrumb", ""], ["emptyState", ""], ["emptyGrid", ""], ["documentEditor", ""], [1, "kb-explorer"], ["class", "kb-state", 4, "ngIf"], ["class", "kb-error", 4, "ngIf"], ["class", "kb-shell", 4, "ngIf"], ["class", "preview-modal", 3, "click", 4, "ngIf"], [1, "kb-state"], [1, "fa", "fa-spinner", "fa-spin"], [1, "kb-error"], [1, "error-card"], [1, "fa", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], [1, "btn", "btn-primary", "mt-4", 3, "click"], [1, "kb-shell"], [1, "kb-titlebar"], [1, "fa", "fa-file-text", "kb-titlebar-icon"], [1, "kb-titlebar-text"], ["class", "text-muted", 4, "ngIf"], [1, "kb-ribbon"], [1, "kb-ribbon-group"], [1, "kb-ribbon-btn", 3, "click"], [1, "fa", "fa-list"], [1, "fa", "fa-th-large"], [1, "kb-ribbon-sep"], [1, "kb-ribbon-group", 2, "flex", "1", "max-width", "300px"], [1, "search-input-wrap", 2, "position", "relative", "width", "100%"], [1, "fa", "fa-search", 2, "position", "absolute", "left", "10px", "top", "12px", "color", "#888"], ["type", "text", "placeholder", "Search documents...", 2, "width", "100%", "height", "36px", "padding-left", "32px", "padding-right", "12px", "border", "1px solid #ddd", "border-radius", "4px", "font-family", "'Lexend'", 3, "ngModelChange", "ngModel"], [1, "kb-addressbar"], [1, "kb-nav-btn", 3, "click", "title"], ["name", "folder", 2, "color", "#444", 3, "size"], [1, "kb-breadcrumb"], [4, "ngIf", "ngIfElse"], [1, "kb-addr-filters"], [1, "filter-label"], [1, "filter-wrap"], [1, "addr-filter-btn", 3, "click"], [1, "fa", "fa-filter"], [4, "ngIf"], ["class", "addr-dropdown", 3, "click", 4, "ngIf"], ["class", "addr-clear-btn", 3, "click", 4, "ngIf"], [1, "kb-content"], [1, "kb-nav-pane"], [1, "nav-pane-header"], [1, "nav-item", 3, "click"], [1, "nav-chevron"], [1, "fa", "fa-fw"], ["name", "folder", 1, "nav-folder-icon", 3, "size"], [1, "nav-label"], ["class", "nav-count", 4, "ngIf"], ["class", "nav-item", 3, "selected", "click", 4, "ngIf"], [1, "kb-file-area"], [1, "kb-file-area-header"], [1, "fah-title"], ["class", "fah-count", 4, "ngIf"], ["class", "fah-download-all", "title", "Download all files as a zip", 3, "disabled", "click", 4, "ngIf"], ["class", "kb-file-scroll", 4, "ngIf"], ["class", "kb-file-scroll kb-grid-scroll", 4, "ngIf"], ["class", "kb-details-pane", 4, "ngIf"], [1, "text-muted"], [1, "bc-seg", 3, "click"], ["class", "bc-sep", 4, "ngIf"], ["class", "bc-seg bc-active", 4, "ngIf"], [1, "bc-sep"], [1, "bc-seg", "bc-active"], [1, "addr-dropdown", 3, "click"], [1, "addr-dd-item", 3, "click"], ["class", "addr-dd-item", 3, "hidden", "selected", "click", 4, "ngFor", "ngForOf"], [1, "addr-dd-item", 3, "click", "hidden"], [1, "addr-clear-btn", 3, "click"], [1, "fa", "fa-times"], [1, "nav-count"], ["name", "file-text", 1, "nav-folder-icon", 3, "size"], [1, "fah-count"], ["title", "Download all files as a zip", 1, "fa
1966h-download-all", 3, "click", "disabled"], [1, "fa", 3, "ngClass"], [1, "kb-file-scroll"], ["class", "exp-table", 4, "ngIf", "ngIfElse"], [1, "exp-table"], [1, "col-name"], [1, "col-type"], [1, "col-date"], [1, "col-act"], [3, "row-selected", "click", "dblclick", 4, "ngFor", "ngForOf"], [3, "click", "dblclick"], [1, "cell-name"], [1, "file-icon-wrap", 3, "ngClass"], [3, "name", "size"], [1, "file-name-text", 3, "title"], [1, "row-actions", 3, "click"], ["title", "View file", 1, "row-act-btn", 3, "click"], [1, "fa", "fa-eye"], ["title", "Download file", 1, "row-act-btn", 3, "click"], [1, "fa", "fa-download"], [1, "kb-empty"], ["name", "folder-open", 2, "color", "#bbb", 3, "size"], [1, "kb-file-scroll", "kb-grid-scroll"], ["class", "icon-grid", 4, "ngIf", "ngIfElse"], [1, "icon-grid"], ["class", "icon-card", 3, "card-selected", "click", "dblclick", 4, "ngFor", "ngForOf"], [1, "icon-card", 3, "click", "dblclick"], [1, "icon-card-icon", 3, "ngClass"], [1, "icon-card-name", 3, "title"], [1, "kb-details-pane"], [1, "dp-header"], [1, "dp-icon-wrap", 3, "ngClass"], [1, "dp-title-area"], [1, "dp-filename", 3, "title"], ["class", "dp-meta", 4, "ngIf"], [1, "dp-close", 3, "click"], [1, "dp-actions"], [1, "dp-action-btn", "dp-primary", 3, "click", "disabled"], [1, "dp-action-btn", 3, "click", "disabled"], [1, "dp-meta"], [1, "preview-modal", 3, "click"], [1, "preview-content", 3, "click"], [1, "preview-header"], [1, "preview-title"], [1, "preview-header-actions", 2, "display", "flex", "align-items", "center", "gap", "8px"], ["title", "Download File", 1, "preview-download", 3, "click"], [1, "preview-close", 3, "click"], [1, "preview-body"], ["class", "preview-error", 4, "ngIf"], ["class", "preview-html", 4, "ngIf"], ["class", "preview-document-editor-container", "style", "width: 100%; height: 100%; border: 1px solid #ddd; background: #fff; position: relative;", 4, "ngIf"], ["type", "application/pdf", "class", "preview-embed", 3, "src", 4, "ngIf"], ["class", "preview-iframe", 3, "src", 4, "ngIf"], ["class", "preview-loading", 4, "ngIf"], [1, "preview-error"], [1, "error-title"], [1, "btn", "btn-primary", 3, "click"], [1, "preview-html"], [1, "document-paper", 3, "innerHTML"], [1, "preview-document-editor-container", 2, "width", "100%", "height", "100%", "border", "1px solid #ddd", "background", "#fff", "position", "relative"], [2, "width", "100%", "height", "100%", "display", "block", 3, "isReadOnly", "enableSelection", "height", "width"], ["type", "application/pdf", 1, "preview-embed", 3, "src"], [1, "preview-iframe", 3, "src"], [1, "preview-loading"]], template: function RfpDocumentsComponent_Template(rf, ctx) { 1967 if (rf & 1) { 1968 \u0275\u0275elementStart(0, "section", 4); 1969 \u0275\u0275template(1, RfpDocumentsComponent_div_1_Template, 3, 0, "div", 5)(2, RfpDocumentsComponent_div_2_Template, 7, 1, "div", 6)(3, RfpDocumentsComponent_div_3_Template, 60, 29, "div", 7)(4, RfpDocumentsComponent_div_4_Template, 17, 7, "div", 8); 1970 \u0275\u0275elementEnd(); 1971 } 1972 if (rf & 2) { 1973 \u0275\u0275advance(); 1974 \u0275\u0275property("ngIf", ctx.loading); 1975 \u0275\u0275advance(); 1976 \u0275\u0275property("ngIf", ctx.error); 1977 \u0275\u0275advance(); 1978 \u0275\u0275property("ngIf", !ctx.loading && !ctx.error); 1979 \u0275\u0275advance(); 1980 \u0275\u0275property("ngIf", ctx.previewFile); 1981 } 1982 }, dependencies: [CommonModule, NgClass, NgForOf, NgIf, UpperCasePipe, RouterModule, FormsModule, DefaultValueAccessor, NgControlStatus, NgModel, LucideAngularModule, LucideAngularComponent, DocumentEditorModule, DocumentEditorComponent], styles: ['\n\n.kb-explorer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: calc(100vh - 70px);\n background: #f3f3f3;\n font-family:\n "Inter",\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 14px;\n color: #151C28;\n overflow: hidden;\n}\n.kb-shell[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n}\n.kb-titlebar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #e8e8e8;\n border-bottom: 1px solid #cccccc;\n height: 36px;\n}\n.kb-titlebar-icon[_ngcontent-%COMP%] {\n color: #0078d4;\n font-size: 14px;\n}\n.kb-titlebar-text[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #1f1f1f;\n flex: 1;\n}\n.kb-titlebar-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n.kb-titlebar-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n color: #444;\n font-size: 13px;\n}\n.kb-titlebar-btn[_ngcontent-%COMP%]:hover {\n background: #d0d0d0;\n}\n.kb-ribbon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 4px 8px;\n background: #f0f0f0;\n border-bottom: 1px solid #d0d0d0;\n min-height: 52px;\n flex-wrap: wrap;\n}\n.kb-ribbon-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n.kb-ribbon-btn[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n padding: 4px 10px;\n border: 1px solid transparent;\n border-radius: 3px;\n background: none;\n cursor: pointer;
1982\n color: #1f1f1f;\n font-size: 11px;\n min-width: 48px;\n transition: all 0.12s;\n}\n.kb-ribbon-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #444;\n}\n.kb-ribbon-btn[_ngcontent-%COMP%]:hover {\n background: #dce6f7;\n border-color: #b3d0f5;\n}\n.kb-ribbon-btn.active[_ngcontent-%COMP%] {\n background: #cce0fc;\n border-color: #0078d4;\n}\n.kb-ribbon-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0078d4;\n}\n.kb-ribbon-sep[_ngcontent-%COMP%] {\n width: 1px;\n height: 38px;\n background: #c8c8c8;\n margin: 0 6px;\n}\n.kb-ribbon-select[_ngcontent-%COMP%] {\n border: 1px solid #bbb;\n border-radius: 3px;\n padding: 3px 6px;\n font-size: 12px;\n background: #fff;\n height: 26px;\n cursor: pointer;\n color: #1f1f1f;\n}\n.kb-ribbon-spacer[_ngcontent-%COMP%] {\n flex: 1;\n}\n.kb-ribbon-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n}\n.kb-ribbon-tabs[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n padding: 3px 10px;\n border: 1px solid transparent;\n border-radius: 8px;\n background: none;\n cursor: pointer;\n font-size: 11px;\n color: #444;\n transition: all 0.12s;\n}\n.kb-ribbon-tabs[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover {\n background: #dce6f7;\n border-color: #b3d0f5;\n}\n.kb-ribbon-tabs[_ngcontent-%COMP%] button.tab-active[_ngcontent-%COMP%] {\n background: #0078d4;\n color: #fff;\n border-color: #0078d4;\n}\n.kb-addressbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n background: #fff;\n border-bottom: 1px solid #d0d0d0;\n min-height: 36px;\n}\n.kb-nav-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 7px;\n border-radius: 3px;\n color: #151C28;\n font-size: 14px;\n}\n.kb-nav-btn[_ngcontent-%COMP%]:hover {\n background: #e8e8e8;\n}\n.kb-breadcrumb[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0;\n flex: 1;\n padding: 0 4px;\n border: 1px solid #d0d0d0;\n border-radius: 3px;\n background: #fff;\n min-height: 28px;\n}\n.bc-seg[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 0 8px;\n height: 24px;\n cursor: pointer;\n color: #151C28;\n font-size: 14px;\n border-radius: 2px;\n transition: background 0.1s;\n}\n.bc-seg[_ngcontent-%COMP%]:hover {\n background: #e5f0fb;\n color: #0078d4;\n}\n.bc-seg.bc-active[_ngcontent-%COMP%] {\n color: #151C28;\n cursor: default;\n font-weight: 600;\n}\n.bc-seg.bc-active[_ngcontent-%COMP%]:hover {\n background: none;\n color: #151C28;\n}\n.bc-arrow[_ngcontent-%COMP%] {\n color: #888;\n font-size: 9px;\n padding: 0 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.kb-addr-filters[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.filter-label[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #151C28;\n font-weight: 600;\n margin-right: 4px;\n}\n.filter-wrap[_ngcontent-%COMP%] {\n position: relative;\n}\n.addr-filter-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid #bbb;\n border-radius: 8px;\n background: #f0f0f0;\n cursor: pointer;\n font-family:\n "Inter",\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 12px;\n color: #151C28;\n white-space: nowrap;\n transition: all 0.12s;\n}\n.addr-filter-btn[_ngcontent-%COMP%]:hover, \n.addr-filter-btn.active[_ngcontent-%COMP%] {\n background: #cce0fc;\n border-color: #0078d4;\n color: #0078d4;\n}\n.addr-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 2px);\n left: 0;\n min-width: 140px;\n background: #fff;\n border: 1px solid #c8c8c8;\n border-radius: 3px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n z-index: 200;\n padding: 2px;\n max-height: 220px;\n overflow-y: auto;\n}\n.addr-dd-item[_ngcontent-%COMP%] {\n padding: 5px 10px;\n font-size: 14px;\n cursor: pointer;\n color: #151C28;\n border-radius: 2px;\n}\n.addr-dd-item[_ngcontent-%COMP%]:hover {\n background: #e5f0fb;\n}\n.addr-dd-item.selected[_ngcontent-%COMP%] {\n background: #cce0fc;\n color: #0078d4;\n font-weight: 600;\n}\n.addr-clear-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid #f00;\n border-radius: 8px;\n background: #fff5f5;\n color: #c00;\n cursor: pointer;\n font-size: 12px;\n transition: all 0.12s;\n}\n.addr-clear-btn[_ngcontent-%COMP%]:hover {\n background: #ffd7d7;\n}\n.kb-content[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n.kb-nav-pane[_ngcontent-%COMP%] {\n width: 220px;\n min-width: 160px;\n background: #f7f7f7;\n border-right: 1px solid #d0d0d0;\n overflow-y: auto;\n padding: 4px 0;\n flex-shrink: 0;\n}\n.nav-pane-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 10px 2px;\n color: #151C28;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n.nav-toggle-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;
1982\n color: #151C28;\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 2px;\n}\n.nav-toggle-btn[_ngcontent-%COMP%]:hover {\n background: #ddd;\n}\n.nav-section-label[_ngcontent-%COMP%] {\n padding: 8px 10px 2px;\n font-size: 12px;\n color: #151C28;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n.nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n cursor: pointer;\n border-radius: 0;\n transition: background 0.1s;\n -webkit-user-select: none;\n user-select: none;\n min-height: 26px;\n}\n.nav-item[_ngcontent-%COMP%]:hover {\n background: #e5f0fb;\n}\n.nav-item.selected[_ngcontent-%COMP%] {\n background: #cce0fc;\n}\n.nav-item.drag-over[_ngcontent-%COMP%] {\n background: #cce0fc !important;\n outline: 2px dashed #0078d4;\n outline-offset: -2px;\n}\n.nav-chevron[_ngcontent-%COMP%] {\n width: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: #888;\n font-size: 11px;\n}\n.nav-folder-icon[_ngcontent-%COMP%] {\n color: #0078d4;\n font-size: 14px;\n flex-shrink: 0;\n}\n.nav-icon-success[_ngcontent-%COMP%] {\n color: #107c10 !important;\n}\n.nav-label[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #151C28;\n}\n.nav-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #888;\n background: #e0e0e0;\n border-radius: 8px;\n padding: 0 5px;\n}\n.nav-rename[_ngcontent-%COMP%], \n.nav-delete[_ngcontent-%COMP%] {\n display: none;\n background: none;\n border: none;\n cursor: pointer;\n font-size: 12px;\n padding: 1px 4px;\n border-radius: 2px;\n}\n.nav-rename[_ngcontent-%COMP%] {\n color: #0078d4;\n}\n.nav-delete[_ngcontent-%COMP%] {\n color: #c00;\n}\n.nav-item[_ngcontent-%COMP%]:hover .nav-rename[_ngcontent-%COMP%], \n.nav-item[_ngcontent-%COMP%]:hover .nav-delete[_ngcontent-%COMP%] {\n display: flex;\n}\n.nav-rename[_ngcontent-%COMP%]:hover {\n background: #e5f0fb;\n}\n.nav-delete[_ngcontent-%COMP%]:hover {\n background: #ffd7d7;\n}\n.nav-empty[_ngcontent-%COMP%] {\n padding: 12px 16px;\n color: #151C28;\n font-size: 14px;\n font-style: italic;\n}\n.nav-item-wrap[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n}\n.kb-file-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n background: #fff;\n transition: all 0.2s;\n}\n.kb-file-area-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 12px;\n background: #f7f7f7;\n border-bottom: 1px solid #e0e0e0;\n min-height: 28px;\n}\n.fah-title[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: #151C28;\n}\n.fah-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #888;\n}\n.fah-download-all[_ngcontent-%COMP%] {\n margin-left: auto;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n font-size: 12px;\n font-weight: 600;\n color: #0078d4;\n background: #fff;\n border: 1px solid #0078d4;\n border-radius: 4px;\n cursor: pointer;\n transition: background 0.08s;\n}\n.fah-download-all[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #e5f0fb;\n}\n.fah-download-all[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n.kb-file-scroll[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 0;\n}\n.exp-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n color: #151C28;\n}\n.exp-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n background: #f0f0f0;\n border-bottom: 1px solid #d0d0d0;\n position: sticky;\n top: 0;\n z-index: 10;\n}\n.exp-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 6px 12px;\n font-weight: 600;\n color: #151C28;\n text-align: center;\n white-space: nowrap;\n border-right: 1px solid #e0e0e0;\n font-size: 13px;\n -webkit-user-select: none;\n user-select: none;\n}\n.exp-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th.col-name[_ng
1982content-%COMP%] {\n text-align: left;\n}\n.exp-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n border-bottom: 1px solid #f0f0f0;\n cursor: pointer;\n transition: background 0.08s;\n}\n.exp-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: #e5f0fb;\n}\n.exp-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] {\n background: #cce0fc;\n outline: 1px solid #0078d4;\n}\n.exp-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 6px 12px;\n vertical-align: middle;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.col-name[_ngcontent-%COMP%] {\n width: 100%;\n text-align: left;\n}\n.col-type[_ngcontent-%COMP%] {\n width: 120px;\n text-align: center;\n}\n.col-date[_ngcontent-%COMP%] {\n width: 180px;\n text-align: center;\n color: #5a6472;\n}\n.col-act[_ngcontent-%COMP%] {\n width: 140px;\n text-align: center;\n}\n.cell-name[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.file-name-text[_ngcontent-%COMP%] {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n color: #151C28;\n}\n.cell-owner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n justify-content: center;\n}\n.owner-avatar[_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: #0078d4;\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n font-weight: 700;\n flex-shrink: 0;\n}\n.file-icon-wrap[_ngcontent-%COMP%] {\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n font-size: 16px;\n}\n.icon-pdf[_ngcontent-%COMP%] {\n color: #0078d4;\n}\n.icon-word[_ngcontent-%COMP%] {\n color: #0078d4;\n}\n.icon-excel[_ngcontent-%COMP%] {\n color: #0078d4;\n}\n.icon-image[_ngcontent-%COMP%] {\n color: #0078d4;\n}\n.icon-text[_ngcontent-%COMP%] {\n color: #0078d4;\n}\n.icon-archive[_ngcontent-%COMP%] {\n color: #0078d4;\n}\n.icon-generic[_ngcontent-%COMP%] {\n color: #0078d4;\n}\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: capitalize;\n}\n.status-approved[_ngcontent-%COMP%] {\n background: #e6f4e6;\n color: #107c10;\n border: 1px solid #b3d9b3;\n}\n.status-pending[_ngcontent-%COMP%] {\n background: #fff4ce;\n color: #8a6900;\n border: 1px solid #e8d44d;\n}\n.status-review[_ngcontent-%COMP%] {\n background: #e5f0fb;\n color: #0078d4;\n border: 1px solid #a8d0f5;\n}\n.status-draft[_ngcontent-%COMP%] {\n background: #f0f0f0;\n color: #444;\n border: 1px solid #c8c8c8;\n}\n.row-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n opacity: 1;\n align-items: center;\n justify-content: center;\n}\n.row-act-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 12px;\n padding: 4px;\n border-radius: 4px;\n color: #0078d4;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.row-act-btn[_ngcontent-%COMP%]:hover {\n background: #e5f0fb;\n}\n.row-del-btn[_ngcontent-%COMP%] {\n background: #fee2e2;\n border: 1px solid #fecaca;\n cursor: pointer;\n font-size: 12px;\n padding: 4px;\n border-radius: 4px;\n color: #dc2626;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n}\n.row-del-btn[_ngcontent-%COMP%]:hover {\n background: #fecaca;\n color: #b91c1c;\n}\n.kb-grid-scroll[_ngcontent-%COMP%] {\n padding: 16px;\n}\n.icon-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n align-content: flex-start;\n}\n.icon-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding: 10px 8px 8px;\n border: 1px solid transparent;\n border-radius: 3px;\n cursor: pointer;\n width: 100px;\n transition: all 0.1s;\n text-align: center;\n}\n.icon-card[_ngcontent-%COMP%]:hover {\n background: #e5f0fb;\n border-color: #b3d0f5;\n}\n.icon-card.card-selected[_ngcontent-%COMP%] {\n background: #cce0fc;\n border-color: #0078d4;\n outline: 1px solid #0078d4;\n}\n.icon-card-icon[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 2px;\n}
1982\n.icon-card-name[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #151C28;\n word-break: break-word;\n line-height: 1.3;\n max-height: 36px;\n overflow: hidden;\n width: 100%;\n font-weight: 500;\n}\n.icon-card-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #888;\n}\n.kb-statusbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 3px 12px;\n background: #f0f0f0;\n border-top: 1px solid #d0d0d0;\n font-size: 12px;\n color: #151C28;\n min-height: 22px;\n flex-shrink: 0;\n}\n.sb-selected[_ngcontent-%COMP%] {\n color: #0078d4;\n font-weight: 500;\n}\n.kb-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: #bbb;\n gap: 12px;\n}\n.kb-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n}\n.kb-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.kb-details-pane[_ngcontent-%COMP%] {\n width: 260px;\n border-left: 1px solid #d0d0d0;\n background: #fafafa;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n flex-shrink: 0;\n}\n.dp-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 14px 12px 10px;\n border-bottom: 1px solid #e0e0e0;\n position: relative;\n}\n.dp-icon-wrap[_ngcontent-%COMP%] {\n font-size: 28px;\n flex-shrink: 0;\n}\n.dp-title-area[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n padding-right: 28px;\n}\n.dp-filename[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #151C28;\n word-break: break-word;\n line-height: 1.4;\n margin-bottom: 4px;\n}\n.dp-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #5a6472;\n margin: 0;\n}\n.dp-close[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n background: none;\n border: none;\n cursor: pointer;\n color: #888;\n font-size: 14px;\n padding: 2px 6px;\n border-radius: 3px;\n}\n.dp-close[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n}\n.dp-actions[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 10px 12px;\n border-bottom: 1px solid #e0e0e0;\n}\n.dp-action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: 1px solid #d0d0d0;\n border-radius: 3px;\n background: #f0f0f0;\n cursor: pointer;\n font-size: 14px;\n color: #151C28;\n transition: all 0.12s;\n}\n.dp-action-btn[_ngcontent-%COMP%]:hover {\n background: #e5f0fb;\n border-color: #0078d4;\n color: #0078d4;\n}\n.dp-primary[_ngcontent-%COMP%] {\n background: #0078d4;\n color: #fff;\n border-color: #0078d4;\n}\n.dp-primary[_ngcontent-%COMP%]:hover {\n background: #106ebe;\n color: #fff;\n}\n.dp-danger[_ngcontent-%COMP%] {\n color: #c00;\n border-color: #e0b0b0;\n background: #fff5f5;\n}\n.dp-danger[_ngcontent-%COMP%]:hover {\n background: #ffd7d7;\n border-color: #c00;\n}\n.dp-status-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n}\n.status-btn[_ngcontent-%COMP%] {\n flex: 1;\n padding: 6px;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n border: 1px solid transparent;\n transition: all 0.12s;\n background: #f0f0f0;\n color: #151C28;\n}\n.btn-pending[_ngcontent-%COMP%]:hover {\n background: #fff4ce;\n border-color: #e8d44d;\n color: #8a6900;\n}\n.btn-pending.active[_ngcontent-%COMP%] {\n background: #fff4ce;\n border-color: #e8d44d;\n color: #8a6900;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.btn-approved[_ngcontent-%COMP%]:hover {\n background: #e6f4e6;\n border-color: #107c10;\n color: #107c10;\n}\n.btn-approved.active[_ngcontent-%COMP%] {\n background: #107c10;\n color: #fff;\n border-color: #107c10;\n box-shadow: 0 2px 4px rgba(16, 124, 16, 0.3);\n}\n.dp-section[_ngcontent-%COMP%] {\n padding: 10px 12px;\n border-bottom: 1px solid #e0e0e0;\n}\n.dp-section-title[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n color: #151C28;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n}\n.dp-prop[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n gap: 8px;\n margin-bottom: 5px;\n}\n.dp-prop-key[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #888;\n flex-shrink: 0;\n}\n.dp-prop-val[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #151C28;\n font-weight: 600;\n text-align: right;\n word-break: break-word;\n}\n.dp-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-bottom: 8px;\n}\n.dp-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: #e5f0fb;\n border: 1px solid #b3d0f5;\n border-radius: 10px;\n font-size: 12px;\n color: #0078d4;\n}\n.tag-remove[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;
1982\n color: #0078d4;\n font-size: 13px;\n font-weight: bold;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.tag-remove[_ngcontent-%COMP%]:hover {\n color: #c00;\n}\n.dp-tag-input-wrap[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n.dp-tag-input-wrap[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n height: 24px;\n padding: 0 8px;\n border: 1px solid #d0d0d0;\n border-radius: 3px;\n font-size: 12px;\n background: #fff;\n}\n.dp-tag-input-wrap[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n background: #f0f0f0;\n border: 1px solid #d0d0d0;\n border-radius: 3px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #444;\n}\n.dp-tag-input-wrap[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #e5f0fb;\n border-color: #0078d4;\n color: #0078d4;\n}\n.dp-tag-input-wrap[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.dp-version[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-bottom: 8px;\n}\n.dp-ver-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: #0078d4;\n border: 2px solid #fff;\n box-shadow: 0 0 0 1px #0078d4;\n flex-shrink: 0;\n margin-top: 3px;\n}\n.dp-version-dim[_ngcontent-%COMP%] {\n opacity: 0.5;\n}\n.dp-version-dim[_ngcontent-%COMP%] .dp-ver-dot[_ngcontent-%COMP%] {\n background: #ccc;\n box-shadow: 0 0 0 1px #ccc;\n}\n.dp-ver-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #151C28;\n}\n.dp-ver-date[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 400;\n color: #888;\n margin-left: 6px;\n}\n.dp-ver-sub[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #888;\n}\n.kb-state[_ngcontent-%COMP%] {\n padding: 20px;\n display: flex;\n align-items: center;\n gap: 8px;\n color: #666;\n font-size: 13px;\n}\n.kb-error[_ngcontent-%COMP%] {\n padding: 10px 16px;\n background: #fff0f0;\n border: 1px solid #f5c6c6;\n color: #c00;\n margin: 8px;\n border-radius: 4px;\n font-size: 12px;\n}\n.preview-modal[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem;\n}\n.preview-content[_ngcontent-%COMP%] {\n background: #fff;\n border-radius: 6px;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\n max-width: 75vw;\n width: 75%;\n max-height: 90vh;\n height: 90%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.preview-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n border-bottom: 1px solid #e5e7eb;\n}\n.preview-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1f1f1f;\n margin: 0;\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.preview-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: #6b7280;\n font-size: 20px;\n font-weight: bold;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: 3px;\n}\n.preview-close[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n}\n.preview-download[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: #6b7280;\n font-size: 16px;\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 3px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n.preview-download[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n color: #0078d4;\n}\n.preview-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n background: #525659;\n position: relative;\n padding: 0;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n.preview-html[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n overflow-y: auto;\n padding: 0.5rem 0.5rem;\n background: #525659;\n}\n.document-paper[_ngcontent-%COMP%] {\n background: #fff;\n max-width: 100%;\n margin: 0 auto;\n padding: 1rem 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n border-radius: 4px;\n}\n.preview-iframe[_ngcontent-%COMP%], \n.preview-embed[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border: none;\n display: block;\n flex: 1;\n min-height: 0;\n}\n.preview-loading[_ngcontent-%COMP%], \n.preview-error[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n gap: 12px;\n}\n.error-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #c00;\n}\n.error-message[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #666;\n max-width: 400px;\n text-align: center;\n}\n.dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 2000;\n}\n.dialog-content[_ngcontent-%COMP%] {\n background: #fff;\n border-radius: 6px;\n max-width: 90vw;\n max-height: 90vh;\n overflow-y: auto;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\n}\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 16px;\n border-bottom: 1px solid #e5e7eb;\n}\n.dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n}\n.dialog-body[_ngcontent-%COMP%] {\n padding: 16px;\n}\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 16px;\n border-top: 1px solid #e5e7eb;\n}\n.btn[_ngcontent-%COMP%] {\n padding: 7px 16px;\n border-radius: 4px;\n border: 1px solid #d0d0d0;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.12s;\n}\n.btn-primary[_ngcontent-%COMP%] {\n background: #0078d4;\n color: #fff;\n border-color: #0078d4;\n}\n.btn-primary[_ngcontent-%COMP%]:hover {\n background: #106ebe;\n}\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;
1982\n cursor: not-allowed;\n}\n.btn-secondary[_ngcontent-%COMP%] {\n background: #f0f0f0;\n color: #151C28;\n}\n.btn-secondary[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n}\n.btn-secondary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.confirm-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 3000;\n}\n.confirm-dialog-content[_ngcontent-%COMP%] {\n background: #fff;\n border-radius: 8px;\n padding: 24px;\n max-width: 420px;\n width: 90%;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\n}\n.btn-professional[_ngcontent-%COMP%] {\n padding: 7px 16px;\n border-radius: 4px;\n border: 1px solid transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.12s;\n}\n.btn-outline[_ngcontent-%COMP%] {\n background: #f0f0f0;\n border-color: #d0d0d0;\n color: #151C28;\n}\n.btn-outline[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n}\n.btn-danger[_ngcontent-%COMP%] {\n background: #d32f2f;\n color: #fff;\n border-color: #d32f2f;\n}\n.btn-danger[_ngcontent-%COMP%]:hover {\n background: #b71c1c;\n}\n.toast-notification[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 9999;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n min-width: 280px;\n}\n.toast-notification.success[_ngcontent-%COMP%] {\n background: #107c10;\n color: #fff;\n}\n.toast-notification.error[_ngcontent-%COMP%] {\n background: #d32f2f;\n color: #fff;\n}\n.toast-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n}\n.toast-message[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n}\n.toast-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: inherit;\n cursor: pointer;\n opacity: 0.8;\n font-size: 14px;\n}\n.toast-close[_ngcontent-%COMP%]:hover {\n opacity: 1;\n}\n.flex[_ngcontent-%COMP%] {\n display: flex;\n}\n.items-center[_ngcontent-%COMP%] {\n align-items: center;\n}\n.gap-2[_ngcontent-%COMP%] {\n gap: 8px;\n}\n.gap-1[_ngcontent-%COMP%] {\n gap: 4px;\n}\n.font-medium[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n.font-semibold[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n.font-bold[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n.text-sm[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n.text-xs[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n.truncate[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.w-full[_ngcontent-%COMP%] {\n width: 100%;\n}\n.h-10[_ngcontent-%COMP%] {\n height: 40px;\n}\n.px-3[_ngcontent-%COMP%] {\n padding-left: 12px;\n padding-right: 12px;\n}\n.rounded-md[_ngcontent-%COMP%] {\n border-radius: 6px;\n}\n.border[_ngcontent-%COMP%] {\n border: 1px solid #d0d0d0;\n}\n.bg-background[_ngcontent-%COMP%] {\n background: #fff;\n}
1982\n.space-y-4[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] + *[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n.space-y-2[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] + *[_ngcontent-%COMP%] {\n margin-top: 8px;\n}\n.space-y-1\\.5[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] + *[_ngcontent-%COMP%] {\n margin-top: 6px;\n}\n.hidden[_ngcontent-%COMP%] {\n display: none;\n}\n.max-h-32[_ngcontent-%COMP%] {\n max-height: 128px;\n}\n.overflow-y-auto[_ngcontent-%COMP%] {\n overflow-y: auto;\n}\n.border-dashed[_ngcontent-%COMP%] {\n border-style: dashed;\n}\n.text-center[_ngcontent-%COMP%] {\n text-align: center;\n}\n.cursor-pointer[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n.p-2[_ngcontent-%COMP%] {\n padding: 8px;\n}\n.p-8[_ngcontent-%COMP%] {\n padding: 32px;\n}\n.text-muted-foreground[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n.hover\\:text-foreground[_ngcontent-%COMP%]:hover {\n color: #151C28;\n}\n.text-lg[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n.col-span-2[_ngcontent-%COMP%] {\n grid-column: span 2;\n}\n/*# sourceMappingURL=rfp-documents.component-6FWKV3LY.css.map */'] }); 1983}; 1984(() => { 1985 (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RfpDocumentsComponent, [{ 1986 type: Component, 1987 args: [{ selector: "app-rfp-documents", standalone: true, imports: [CommonModule, RouterModule, FormsModule, LucideAngularModule, DocumentEditorModule], template: `<section class="kb-explorer"> 1988 1989 <!-- ===== LOADING / ERROR ===== --> 1990 <div *ngIf="loading" class="kb-state"> 1991 <i class="fa fa-spinner fa-spin"></i> Loading RFP documents\u2026 1992 </div> 1993 <div *ngIf="error" class="kb-error"> 1994 <div class="error-card"> 1995 <i class="fa fa-exclamation-triangle error-icon"></i> 1996 <p class="error-message">{{ error }}</p> 1997 <button class="btn btn-primary mt-4" (click)="goToBack()">Go Back</button> 1998 </div> 1999 </div> 2000 2001 <div class="kb-shell" *ngIf="!loading && !error"> 2002 2003 <!-- \u2500\u2500 TITLE BAR \u2500\u2500 --> 2004 <div class="kb-titlebar"> 2005 <i class="fa fa-file-text kb-titlebar-icon"></i> 2006 <span class="kb-titlebar-text">RFP Documents <span class="text-muted" *ngIf="rfpTitle">- {{ rfpTitle }}</span></span> 2007 </div> 2008 2009 <!-- \u2500\u2500 RIBBON / TOOLBAR \u2500\u2500 --> 2010 <div class="kb-ribbon"> 2011 <div class="kb-ribbon-group"> 2012 <button class="kb-ribbon-btn" [class.active]="isList" (click)="gotoListView()"> 2013 <i class="fa fa-list"></i> 2014 <span>Details</span> 2015 </button> 2016 <button class="kb-ribbon-btn" [class.active]="isGrid" (click)="gotoGridView()"> 2017 <i class="fa fa-th-large"></i> 2018 <span>Icons</span> 2019 </button> 2020 </div> 2021 <div class="kb-ribbon-sep"></div> 2022 2023 <!-- Search Input --> 2024 <div class="kb-ribbon-group" style="flex: 1; max-width: 300px;"> 2025 <div class="search-input-wrap" style="position: relative; width: 100%;"> 2026 <i class="fa fa-search" style="position: absolute; left: 10px; top: 12px; color: #888;"></i> 2027 <input type="text" 2028 [(ngModel)]="searchTerm" 2029 (ngModelChange)="filterFiles()" 2030 placeholder="Search documents..." 2031 style="width: 100%; height: 36px; padding-left: 32px; padding-right: 12px; border: 1px solid #ddd; border-radius: 4px; font-family: 'Lexend';" /> 2032 </div> 2033 </div> 2034 </div> 2035 2036 <!-- \u2500\u2500 ADDRESS BAR \u2500\u2500 --> 2037 <div class="kb-addressbar"> 2038 <button class="kb-nav-btn" (click)="setActiveTab('initial')" [title]="isSled2 ? 'RFP Package' : 'All Files'"> 2039 <lucide-icon name="folder" [size]="16" style="color: #444"></lucide-icon> 2040 </button> 2041 <div class="kb-breadcrumb"> 2042 <ng-container *ngIf="isSled2; else standardBreadcrumb"> 2043 <span class="bc-seg" [class.bc-active]="activeTab === 'initial'" (click)="setActiveTab('initial')">RFP Package</span> 2044 <span class="bc-sep" *ngIf="activeTab === 'amendments'">/</span> 2045 <span class="bc-seg bc-active" *ngIf="activeTab === 'amendments'">Amendments</span> 2046 </ng-container> 2047 <ng-template #standardBreadcrumb>
2048 <span class="bc-seg bc-active">All Documents</span> 2049 </ng-template> 2050 </div> 2051 <!-- Search / Filters --> 2052 <div class="kb-addr-filters"> 2053 <span class="filter-label">Filters:</span> 2054 <!-- Type Filter --> 2055 <div class="filter-wrap"> 2056 <button class="addr-filter-btn" [class.active]="selectedType !== 'All'" (click)="toggleDropdown('type', $event)"> 2057 <i class="fa fa-filter"></i> Type<span *ngIf="selectedType !== 'All'"> ({{selectedType}})</span> 2058 </button> 2059 <div class="addr-dropdown" *ngIf="activeDropdown === 'type'" (click)="$event.stopPropagation()"> 2060 <div class="addr-dd-item" [class.selected]="selectedType === 'All'" (click)="selectFilter('type', 'All')">All</div> 2061 <div class="addr-dd-item" *ngFor="let t of availableTypes" [hidden]="t === 'All'" [class.selected]="selectedType === t" (click)="selectFilter('type', t)">{{t}}</div> 2062 </div> 2063 </div> 2064 2065 <button *ngIf="selectedType !== 'All' || searchTerm" 2066 class="addr-clear-btn" (click)="resetFilters()"> 2067 <i class="fa fa-times"></i> Clear 2068 </button> 2069 </div> 2070 </div> 2071 2072 <!-- \u2500\u2500 MAIN CONTENT AREA \u2500\u2500 --> 2073 <div class="kb-content"> 2074 2075 <!-- Left Nav Pane --> 2076 <nav class="kb-nav-pane"> 2077 <div class="nav-pane-header"> 2078 <span>Navigation</span> 2079 </div> 2080 2081 <div class="nav-item" [class.selected]="activeTab === 'initial'" (click)="setActiveTab('initial')"> 2082 <span class="nav-chevron"><i class="fa fa-fw"></i></span> 2083 <lucide-icon name="folder" class="nav-folder-icon" [size]="16"></lucide-icon> 2084 <span class="nav-label">{{ isSled2 ? 'RFP Package' : 'All RFP Files' }}</span> 2085 <span class="nav-count" *ngIf="files.length">{{ files.length }}</span> 2086 </div> 2087 2088 <div *ngIf="isSled2" class="nav-item" [class.selected]="activeTab === 'amendments'" (click)="setActiveTab('amendments')"> 2089 <span class="nav-chevron"><i class="fa fa-fw"></i></span> 2090 <lucide-icon name="file-text" class="nav-folder-icon" [size]="16"></lucide-icon> 2091 <span class="nav-label">Amendments</span> 2092 <span class="nav-count" *ngIf="amendments.length">{{ amendments.length }}</span> 2093 </div> 2094 </nav> 2095 2096 <!-- File Area --> 2097 <div class="kb-file-area" [class.has-details]="!!selectedFile"> 2098 2099 <!-- Status bar top --> 2100 <div class="kb-file-area-header"> 2101 <span class="fah-title">{{ isSled2 ? (activeTab === 'initial' ? 'RFP Package' : 'RFP Amendments') : 'RFP Source Files' }}</span> 2102 <span class="fah-count" *ngIf="filteredFiles.length">{{ filteredFiles.length }} item{{ filteredFiles.length !== 1 ? 's' : '' }}</span> 2103 <button *ngIf="(activeTab === 'amendments' ? amendments : files).length" 2104 class="fah-download-all" 2105 [disabled]="isDownloadingAll" 2106 (click)="downloadAllFiles()" 2107 title="Download all files as a zip"> 2108 <i class="fa" [ngClass]="isDownloadingAll ? 'fa-spinner fa-spin' : 'fa-download'"></i> 2109 {{ isDownloadingAll ? 'Downloading...' : 'Download All' }} 2110 </button> 2111 </div> 2112 2113 <!-- \u2500\u2500 LIST VIEW (Details) \u2500\u2500 --> 2114 <div class="kb-file-scroll" *ngIf="isList"> 2115 <table class="exp-table" *ngIf="filteredFiles.length; else emptyState"> 2116 <thead> 2117 <tr> 2118 <th class="col-name">Name</th> 2119 <th class="col-type">Type</th> 2120 <th class="col-date">Created/Uploaded Date</th> 2121 <th class="col-act">Actions</th> 2122 </tr> 2123 </thead> 2124 <tbody> 2125 <tr *ngFor="let file of filteredFiles" 2126 [class.row-selected]="selectedFile?.id === file.id" 2127 (click)="selectFile(file)" 2128 (dblclick)="previewFolderFile(file)"> 2129 <td class="col-name"> 2130 <div class="cell-name"> 2131 <div class="file-icon-wrap" [ngClass]="getFileIconClass(file.fileType)"> 2132 <lucide-icon [name]="getFileIcon(file.fileType)" [size]="16"></lucide-icon> 2133 </div>
2134 <span class="file-name-text" [title]="file.fileName">{{ file.fileName }}</span> 2135 </div> 2136 </td> 2137 <td class="col-type">{{ file.fileType | uppercase }}</td> 2138 <td class="col-date">{{ file.uploadedDate }}</td> 2139 <td class="col-act"> 2140 <div class="row-actions" (click)="$event.stopPropagation()"> 2141 <button class="row-act-btn" (click)="previewFolderFile(file)" title="View file"> 2142 <i class="fa fa-eye"></i> 2143 </button> 2144 <button class="row-act-btn" (click)="downloadFolderFile(file)" title="Download file"> 2145 <i class="fa fa-download"></i> 2146 </button> 2147 </div> 2148 </td> 2149 </tr> 2150 </tbody> 2151 </table> 2152 <ng-template #emptyState> 2153 <div class="kb-empty"> 2154 <lucide-icon name="folder-open" [size]="48" style="color: #bbb"></lucide-icon> 2155 <p>{{ isSled2 ? (activeTab === 'initial' ? 'No documents found matching search criteria.' : 'No amendments found for this RFP.') : 'No documents found matching search criteria.' }}</p> 2156 </div> 2157 </ng-template> 2158 </div> 2159 2160 <!-- \u2500\u2500 GRID VIEW (Icons) \u2500\u2500 --> 2161 <div class="kb-file-scroll kb-grid-scroll" *ngIf="isGrid"> 2162 <div class="icon-grid" *ngIf="filteredFiles.length; else emptyGrid"> 2163 <div *ngFor="let file of filteredFiles" 2164 class="icon-card" 2165 [class.card-selected]="selectedFile?.id === file.id" 2166 (click)="selectFile(file)" 2167 (dblclick)="previewFolderFile(file)"> 2168 <div class="icon-card-icon" [ngClass]="getFileIconClass(file.fileType)"> 2169 <lucide-icon [name]="getFileIcon(file.fileType)" [size]="32"></lucide-icon> 2170 </div> 2171 <span class="icon-card-name" [title]="file.fileName">{{ file.fileName }}</span> 2172 </div> 2173 </div> 2174 <ng-template #emptyGrid> 2175 <div class="kb-empty"> 2176 <lucide-icon name="folder-open" [size]="48" style="color: #bbb"></lucide-icon> 2177 <p>{{ isSled2 ? (activeTab === 'initial' ? 'No documents found matching search criteria.' : 'No amendments found for this RFP.') : 'No documents found matching search criteria.' }}</p> 2178 </div> 2179 </ng-template> 2180 </div> 2181 2182 </div> 2183 2184 <!-- Details Pane --> 2185 <aside class="kb-details-pane" *ngIf="selectedFile"> 2186 <div class="dp-header"> 2187 <div class="dp-icon-wrap" [ngClass]="getFileIconClass(selectedFile.fileType)"> 2188 <lucide-icon [name]="getFileIcon(selectedFile.fileType)" [size]="32"></lucide-icon> 2189 </div> 2190 <div class="dp-title-area"> 2191 <p class="dp-filename" [title]="selectedFile.fileName">{{ selectedFile.fileName }}</p> 2192 <p class="dp-meta" *ngIf="selectedFile.uploadedDate && selectedFile.uploadedDate !== 'N/A'"> 2193 Created: {{ selectedFile.uploadedDate }} 2194 </p> 2195 </div> 2196 <button class="dp-close" (click)="closeFileDetails()"><i class="fa fa-times"></i></button> 2197 </div> 2198 2199 <div class="dp-actions"> 2200 <button class="dp-action-btn dp-primary" [disabled]="isDownloadingFile || isOpeningFile" (click)="downloadFolderFile(selectedFile)"> 2201 <i class="fa" [ngClass]="isDownloadingFile ? 'fa-spinner fa-spin' : 'fa-download'"></i> 2202 {{ isDownloadingFile ? 'Downloading...' : 'Download' }} 2203 </button> 2204 <button class="dp-action-btn" [disabled]="isDownloadingFile || isOpeningFile" (click)="previewFolderFile(selectedFile)"> 2205 <i class="fa" [ngClass]="isOpeningFile ? 'fa-spinner fa-spin' : 'fa-eye'"></i> 2206 {{ isOpeningFile ? 'Opening...' : 'Open' }} 2207 </button> 2208 </div> 2209 </aside> 2210 </div> 2211 </div> 2212 2213 <!-- ===== PREVIEW MODAL ===== --> 2214 <div *ngIf="previewFile" class="preview-modal" (click)="closePreview()"> 2215 <div class="preview-content" (click)="$event.stopPropagation()"> 2216 <div class="preview-header"> 2217 <h3 class="preview-title">{{ previewFile.name }}</h3> 2218 <div class="preview-header-actions" style="display: flex; align-items: center; gap: 8px;"> 2219 <button (click)="downloadPreviewFile()" class="preview-download" title="Download File"> 2220 <i class="fa fa-download"></i> 2221 </button> 2222 <button (click)="closePreview()" class="preview-close">\xD7</button> 2223 </div> 2224 </div> 2225 <div class="preview-body"> 2226 <div *ngIf="previewError" class="preview-error"> 2227 <p class="error-title">
2227\u26A0\uFE0F Unable to open file</p> 2228 <p class="error-message">{{ previewError }}</p> 2229 <button class="btn btn-primary" (click)="closePreview()">Close</button> 2230 </div> 2231 <div *ngIf="!previewError && previewFile.htmlContent" class="preview-html"> 2232 <div class="document-paper" [innerHTML]="previewFile.htmlContent"></div> 2233 </div> 2234 <div *ngIf="!previewError && !previewFile.htmlContent && (previewFile.type === 'docx' || previewFile.type === 'doc')" class="preview-document-editor-container" style="width: 100%; height: 100%; border: 1px solid #ddd; background: #fff; position: relative;"> 2235 <ejs-documenteditor #documentEditor 2236 [isReadOnly]="true" 2237 [enableSelection]="true" 2238 [height]="'100%'" 2239 [width]="'100%'" 2240 style="width: 100%; height: 100%; display: block;"> 2241 </ejs-documenteditor> 2242 </div> 2243 <embed *ngIf="!previewError && !previewFile.htmlContent && previewFile.url && previewFile.type === 'application/pdf'" [src]="previewFile.url" type="application/pdf" class="preview-embed" /> 2244 <iframe *ngIf="!previewError && !previewFile.htmlContent && previewFile.url && previewFile.type !== 'application/pdf' && previewFile.type !== 'docx' && previewFile.type !== 'doc'" [src]="previewFile.url" class="preview-iframe"></iframe> 2245 <div *ngIf="loadingFile && !previewError" class="preview-loading"><i class="fa fa-spinner fa-spin"></i> Loading...</div> 2246 </div> 2247 </div> 2248 </div> 2249 2250</section> 2251 2252`, styles: ['/* src/app/pages/rfp-documents/rfp-documents.component.scss */\n.kb-explorer {\n display: flex;\n flex-direction: column;\n height: calc(100vh - 70px);\n background: #f3f3f3;\n font-family:\n "Inter",\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 14px;\n color: #151C28;\n overflow: hidden;\n}\n.kb-shell {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n}\n.kb-titlebar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #e8e8e8;\n border-bottom: 1px solid #cccccc;\n height: 36px;\n}\n.kb-titlebar-icon {\n color: #0078d4;\n font-size: 14px;\n}\n.kb-titlebar-text {\n font-size: 12px;\n font-weight: 600;\n color: #1f1f1f;\n flex: 1;\n}\n.kb-titlebar-actions {\n display: flex;\n gap: 4px;\n}\n.kb-titlebar-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n color: #444;\n font-size: 13px;\n}\n.kb-titlebar-btn:hover {\n background: #d0d0d0;\n}\n.kb-ribbon {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 4px 8px;\n background: #f0f0f0;\n border-bottom: 1px solid #d0d0d0;\n min-height: 52px;\n flex-wrap: wrap;\n}\n.kb-ribbon-group {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n.kb-ribbon-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n padding: 4px 10px;\n border: 1px solid transparent;\n border-radius: 3px;\n background: none;\n cursor: pointer;\n color: #1f1f1f;\n font-size: 11px;\n min-width: 48px;\n transition: all 0.12s;\n}\n.kb-ribbon-btn i {\n font-size: 16px;\n color: #444;\n}\n.kb-ribbon-btn:hover {\n background: #dce6f7;\n border-color: #b3d0f5;\n}\n.kb-ribbon-btn.active {\n background: #cce0fc;\n border-color: #0078d4;\n}\n.kb-ribbon-btn.active i {\n color: #0078d4;\n}\n.kb-ribbon-sep {\n width: 1px;\n height: 38px;\n background: #c8c8c8;\n margin: 0 6px;\n}\n.kb-ribbon-select {\n border: 1px solid #bbb;\n border-radius: 3px;\n padding: 3px 6px;\n font-size: 12px;\n background: #fff;\n height: 26px;\n cursor: pointer;\n color: #1f1f1f;\n}\n.kb-ribbon-spacer {\n flex: 1;\n}\n.kb-ribbon-tabs {\n display: flex;\n gap: 2px;\n}\n.kb-ribbon-tabs button {\n padding: 3px 10px;\n border: 1px solid transparent;\n border-radius: 8px;\n background: none;\n cursor: pointer;\n font-size: 11px;\n color: #444;\n transition: all 0.12s;\n}\n.kb-ribbon-tabs button:hover {\n background: #dce6f7;\n border-color: #b3d0f5;\n}\n.kb-ribbon-tabs button.tab-active {\n background: #0078d4;\n color: #fff;\n border-color: #0078d4;\n}\n.kb-addressbar {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n background: #fff;\n border-bottom: 1px solid #d0d0d0;\n min-height: 36px;\n}\n.kb-nav-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 7px;\n border-radius: 3px;\n color: #151C28;\n font-size: 14px;\n}\n.kb-nav-btn:hover {\n background: #e8e8e8;\n}\n.kb-breadcrumb {\n display: flex;\n align-items: center;\n gap: 0;\n flex: 1;\n padding: 0 4px;\n border: 1px solid #d0d0d0;\n border-radius: 3px;\n background: #fff;\n min-height: 28px;\n}\n.bc-seg {\n display: flex;\n align-items: center;\n padding: 0 8px;\n height: 24px;\n cursor: pointer;
2252\n color: #151C28;\n font-size: 14px;\n border-radius: 2px;\n transition: background 0.1s;\n}\n.bc-seg:hover {\n background: #e5f0fb;\n color: #0078d4;\n}\n.bc-seg.bc-active {\n color: #151C28;\n cursor: default;\n font-weight: 600;\n}\n.bc-seg.bc-active:hover {\n background: none;\n color: #151C28;\n}\n.bc-arrow {\n color: #888;\n font-size: 9px;\n padding: 0 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.kb-addr-filters {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.filter-label {\n font-size: 14px;\n color: #151C28;\n font-weight: 600;\n margin-right: 4px;\n}\n.filter-wrap {\n position: relative;\n}\n.addr-filter-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid #bbb;\n border-radius: 8px;\n background: #f0f0f0;\n cursor: pointer;\n font-family:\n "Inter",\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 12px;\n color: #151C28;\n white-space: nowrap;\n transition: all 0.12s;\n}\n.addr-filter-btn:hover,\n.addr-filter-btn.active {\n background: #cce0fc;\n border-color: #0078d4;\n color: #0078d4;\n}\n.addr-dropdown {\n position: absolute;\n top: calc(100% + 2px);\n left: 0;\n min-width: 140px;\n background: #fff;\n border: 1px solid #c8c8c8;\n border-radius: 3px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n z-index: 200;\n padding: 2px;\n max-height: 220px;\n overflow-y: auto;\n}\n.addr-dd-item {\n padding: 5px 10px;\n font-size: 14px;\n cursor: pointer;\n color: #151C28;\n border-radius: 2px;\n}\n.addr-dd-item:hover {\n background: #e5f0fb;\n}\n.addr-dd-item.selected {\n background: #cce0fc;\n color: #0078d4;\n font-weight: 600;\n}\n.addr-clear-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid #f00;\n border-radius: 8px;\n background: #fff5f5;\n color: #c00;\n cursor: pointer;\n font-size: 12px;\n transition: all 0.12s;\n}\n.addr-clear-btn:hover {\n background: #ffd7d7;\n}\n.kb-content {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n.kb-nav-pane {\n width: 220px;\n min-width: 160px;\n background: #f7f7f7;\n border-right: 1px solid #d0d0d0;\n overflow-y: auto;\n padding: 4px 0;\n flex-shrink: 0;\n}\n.nav-pane-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 10px 2px;\n color: #151C28;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n.nav-toggle-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #151C28;\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 2px;\n}\n.nav-toggle-btn:hover {\n background: #ddd;\n}\n.nav-section-label {\n padding: 8px 10px 2px;\n font-size: 12px;\n color: #151C28;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n.nav-item {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n cursor: pointer;\n border-radius: 0;\n transition: background 0.1s;\n -webkit-user-select: none;\n user-select: none;\n min-height: 26px;\n}\n.nav-item:hover {\n background: #e5f0fb;\n}\n.nav-item.selected {\n background: #cce0fc;\n}\n.nav-item.drag-over {\n background: #cce0fc !important;\n outline: 2px dashed #0078d4;\n outline-offset: -2px;\n}\n.nav-chevron {\n width: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: #888;\n font-size: 11px;\n}\n.nav-folder-icon {\n color: #0078d4;\n font-size: 14px;\n flex-shrink: 0;\n}\n.nav-icon-success {\n color: #107c10 !important;\n}\n.nav-label {\n flex: 1;\n font-size: 14px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #151C28;\n}\n.nav-count {\n font-size: 11px;\n color: #888;\n background: #e0e0e0;\n border-radius: 8px;\n padding: 0 5px;\n}\n.nav-rename,\n.nav-delete {\n display: none;\n background: none;\n border: none;\n cursor: pointer;\n font-size: 12px;\n padding: 1px 4px;\n border-radius: 2px;\n}\n.nav-rename {\n color: #0078d4;\n}\n.nav-delete {\n color: #c00;\n}\n.nav-item:hover .nav-rename,\n.nav-item:hover .nav-delete {\n display: flex;\n}\n.nav-rename:hover {\n background: #e5f0fb;\n}\n.nav-delete:hover {\n background: #ffd7d7;\n}
2252\n.nav-empty {\n padding: 12px 16px;\n color: #151C28;\n font-size: 14px;\n font-style: italic;\n}\n.nav-item-wrap {\n display: flex;\n flex-direction: column;\n}\n.kb-file-area {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n background: #fff;\n transition: all 0.2s;\n}\n.kb-file-area-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 12px;\n background: #f7f7f7;\n border-bottom: 1px solid #e0e0e0;\n min-height: 28px;\n}\n.fah-title {\n font-weight: 600;\n font-size: 14px;\n color: #151C28;\n}\n.fah-count {\n font-size: 11px;\n color: #888;\n}\n.fah-download-all {\n margin-left: auto;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n font-size: 12px;\n font-weight: 600;\n color: #0078d4;\n background: #fff;\n border: 1px solid #0078d4;\n border-radius: 4px;\n cursor: pointer;\n transition: background 0.08s;\n}\n.fah-download-all:hover:not(:disabled) {\n background: #e5f0fb;\n}\n.fah-download-all:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n.kb-file-scroll {\n flex: 1;\n overflow: auto;\n padding: 0;\n}\n.exp-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n color: #151C28;\n}\n.exp-table thead tr {\n background: #f0f0f0;\n border-bottom: 1px solid #d0d0d0;\n position: sticky;\n top: 0;\n z-index: 10;\n}\n.exp-table thead th {\n padding: 6px 12px;\n font-weight: 600;\n color: #151C28;\n text-align: center;\n white-space: nowrap;\n border-right: 1px solid #e0e0e0;\n font-size: 13px;\n -webkit-user-select: none;\n user-select: none;\n}\n.exp-table thead th.col-name {\n text-align: left;\n}\n.exp-table tbody tr {\n border-bottom: 1px solid #f0f0f0;\n cursor: pointer;\n transition: background 0.08s;\n}\n.exp-table tbody tr:hover {\n background: #e5f0fb;\n}\n.exp-table tbody tr.row-selected {\n background: #cce0fc;\n outline: 1px solid #0078d4;\n}\n.exp-table td {\n padding: 6px 12px;\n vertical-align: middle;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.col-name {\n width: 100%;\n text-align: left;\n}\n.col-type {\n width: 120px;\n text-align: center;\n}\n.col-date {\n width: 180px;\n text-align: center;\n color: #5a6472;\n}\n.col-act {\n width: 140px;\n text-align: center;\n}\n.cell-name {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.file-name-text {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n color: #151C28;\n}\n.cell-owner {\n display: flex;\n align-items: center;\n gap: 6px;\n justify-content: center;\n}\n.owner-avatar {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: #0078d4;\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n font-weight: 700;\n flex-shrink: 0;\n}\n.file-icon-wrap {\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n font-size: 16px;\n}\n.icon-pdf {\n color: #0078d4;\n}\n.icon-word {\n color: #0078d4;\n}\n.icon-excel {\n color: #0078d4;\n}\n.icon-image {\n color: #0078d4;\n}\n.icon-text {\n color: #0078d4;\n}\n.icon-archive {\n color: #0078d4;\n}\n.icon-generic {\n color: #0078d4;\n}\n.status-badge {\n display: inline-flex;\n align-items: center;\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: capitalize;\n}\n.status-approved {\n background: #e6f4e6;\n color: #107c10;\n border: 1px solid #b3d9b3;\n}\n.status-pending {\n background: #fff4ce;\n color: #8a6900;\n border: 1px solid #e8d44d;\n}\n.status-review {\n background: #e5f0fb;\n color: #0078d4;\n border: 1px solid #a8d0f5;\n}\n.status-draft {\n background: #f0f0f0;\n color: #444;\n border: 1px solid #c8c8c8;\n}\n.row-actions {\n display: flex;\n gap: 8px;\n opacity: 1;\n align-items: center;\n justify-content: center;\n}\n.row-act-btn {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 12px;\n padding: 4px;\n border-radius: 4px;\n color: #0078d4;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.row-act-btn:hover {\n background: #e5f0fb;\n}\n.row-del-btn {\n background: #fee2e2;\n border: 1px solid #fecaca;\n cursor: pointer;\n font-size: 12px;\n padding: 4px;\n border-radius: 4px;\n color: #dc2626;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n}\n.row-del-btn:hover {\n background: #fecaca;\n color: #b91c1c;\n}\n.kb-grid-scroll {\n padding: 16px;\n}\n.icon-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n align-content: flex-start;\n}\n.icon-card {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding: 10px 8px 8px;\n border: 1px solid transparent;\n border-radius: 3px;\n cursor: pointer;\n width: 100px;\n transition: all 0.1s;\n text-align: center;\n}\n.icon-card:hover {\n background: #e5f0fb;\n border-color: #b3d0f5;\n}\n.icon-card.card-selected {\n background: #cce0fc;\n border-color: #0078d4;\n outline: 1px solid #0078d4;\n}\n.icon-card-icon {\n font-size: 32px;\n margin-bottom: 2px;\n}\n.icon-card-name {\n font-size: 13px;\n color: #151C28;\n word-break: break-word;\n line-height: 1.3;\n max-height: 36px;\n overflow: hidden;\n width: 100%;\n font-weight: 500;\n}\n.icon-card-meta {\n font-size: 12px;\n color: #888;\n}\n.kb-statusbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 3px 12px;\n background: #f0f0f0;\n border-top: 1px solid #d0d0d0;\n font-size: 12px;\n color: #151C28;\n min-height: 22px;\n flex-shrink: 0;\n}\n.sb-selected {\n color: #0078d4;\n font-weight: 500;\n}
2252\n.kb-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: #bbb;\n gap: 12px;\n}\n.kb-empty i {\n font-size: 48px;\n}\n.kb-empty p {\n font-size: 14px;\n}\n.kb-details-pane {\n width: 260px;\n border-left: 1px solid #d0d0d0;\n background: #fafafa;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n flex-shrink: 0;\n}\n.dp-header {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 14px 12px 10px;\n border-bottom: 1px solid #e0e0e0;\n position: relative;\n}\n.dp-icon-wrap {\n font-size: 28px;\n flex-shrink: 0;\n}\n.dp-title-area {\n flex: 1;\n min-width: 0;\n padding-right: 28px;\n}\n.dp-filename {\n font-size: 14px;\n font-weight: 600;\n color: #151C28;\n word-break: break-word;\n line-height: 1.4;\n margin-bottom: 4px;\n}\n.dp-meta {\n font-size: 12px;\n color: #5a6472;\n margin: 0;\n}\n.dp-close {\n position: absolute;\n top: 8px;\n right: 8px;\n background: none;\n border: none;\n cursor: pointer;\n color: #888;\n font-size: 14px;\n padding: 2px 6px;\n border-radius: 3px;\n}\n.dp-close:hover {\n background: #e0e0e0;\n}\n.dp-actions {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 10px 12px;\n border-bottom: 1px solid #e0e0e0;\n}\n.dp-action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: 1px solid #d0d0d0;\n border-radius: 3px;\n background: #f0f0f0;\n cursor: pointer;\n font-size: 14px;\n color: #151C28;\n transition: all 0.12s;\n}\n.dp-action-btn:hover {\n background: #e5f0fb;\n border-color: #0078d4;\n color: #0078d4;\n}\n.dp-primary {\n background: #0078d4;\n color: #fff;\n border-color: #0078d4;\n}\n.dp-primary:hover {\n background: #106ebe;\n color: #fff;\n}\n.dp-danger {\n color: #c00;\n border-color: #e0b0b0;\n background: #fff5f5;\n}\n.dp-danger:hover {\n background: #ffd7d7;\n border-color: #c00;\n}\n.dp-status-actions {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n}\n.status-btn {\n flex: 1;\n padding: 6px;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n border: 1px solid transparent;\n transition: all 0.12s;\n background: #f0f0f0;\n color: #151C28;\n}\n.btn-pending:hover {\n background: #fff4ce;\n border-color: #e8d44d;\n color: #8a6900;\n}\n.btn-pending.active {\n background: #fff4ce;\n border-color: #e8d44d;\n color: #8a6900;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.btn-approved:hover {\n background: #e6f4e6;\n border-color: #107c10;\n color: #107c10;\n}\n.btn-approved.active {\n background: #107c10;\n color: #fff;\n border-color: #107c10;\n box-shadow: 0 2px 4px rgba(16, 124, 16, 0.3);\n}\n.dp-section {\n padding: 10px 12px;\n border-bottom: 1px solid #e0e0e0;\n}\n.dp-section-title {\n font-size: 12px;\n font-weight: 700;\n color: #151C28;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n}\n.dp-prop {\n display: flex;\n justify-content: space-between;\n gap: 8px;\n margin-bottom: 5px;\n}\n.dp-prop-key {\n font-size: 13px;\n color: #888;\n flex-shrink: 0;\n}\n.dp-prop-val {\n font-size: 13px;\n color: #151C28;\n font-weight: 600;\n text-align: right;\n word-break: break-word;\n}\n.dp-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-bottom: 8px;\n}\n.dp-tag {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: #e5f0fb;\n border: 1px solid #b3d0f5;\n border-radius: 10px;\n font-size: 12px;\n color: #0078d4;\n}\n.tag-remove {\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n color: #0078d4;\n font-size: 13px;\n font-weight: bold;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.tag-remove:hover {\n color: #c00;\n}\n.dp-tag-input-wrap {\n display: flex;\n gap: 4px;\n}\n.dp-tag-input-wrap input {\n flex: 1;\n height: 24px;\n padding: 0 8px;\n border: 1px solid #d0d0d0;\n border-radius: 3px;\n font-size: 12px;\n background: #fff;\n}\n.dp-tag-input-wrap button {\n width: 24px;\n height: 24px;\n background: #f0f0f0;\n border: 1px solid #d0d0d0;\n border-radius: 3px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;
2252\n color: #444;\n}\n.dp-tag-input-wrap button:hover:not(:disabled) {\n background: #e5f0fb;\n border-color: #0078d4;\n color: #0078d4;\n}\n.dp-tag-input-wrap button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.dp-version {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-bottom: 8px;\n}\n.dp-ver-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: #0078d4;\n border: 2px solid #fff;\n box-shadow: 0 0 0 1px #0078d4;\n flex-shrink: 0;\n margin-top: 3px;\n}\n.dp-version-dim {\n opacity: 0.5;\n}\n.dp-version-dim .dp-ver-dot {\n background: #ccc;\n box-shadow: 0 0 0 1px #ccc;\n}\n.dp-ver-label {\n font-size: 14px;\n font-weight: 600;\n color: #151C28;\n}\n.dp-ver-date {\n font-size: 11px;\n font-weight: 400;\n color: #888;\n margin-left: 6px;\n}\n.dp-ver-sub {\n font-size: 10px;\n color: #888;\n}\n.kb-state {\n padding: 20px;\n display: flex;\n align-items: center;\n gap: 8px;\n color: #666;\n font-size: 13px;\n}\n.kb-error {\n padding: 10px 16px;\n background: #fff0f0;\n border: 1px solid #f5c6c6;\n color: #c00;\n margin: 8px;\n border-radius: 4px;\n font-size: 12px;\n}\n.preview-modal {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem;\n}\n.preview-content {\n background: #fff;\n border-radius: 6px;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\n max-width: 75vw;\n width: 75%;\n max-height: 90vh;\n height: 90%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.preview-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n border-bottom: 1px solid #e5e7eb;\n}\n.preview-title {\n font-size: 14px;\n font-weight: 600;\n color: #1f1f1f;\n margin: 0;\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.preview-close {\n background: none;\n border: none;\n color: #6b7280;\n font-size: 20px;\n font-weight: bold;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: 3px;\n}\n.preview-close:hover {\n background: #f0f0f0;\n}\n.preview-download {\n background: none;\n border: none;\n color: #6b7280;\n font-size: 16px;\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 3px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n.preview-download:hover {\n background: #f0f0f0;\n color: #0078d4;\n}\n.preview-body {\n flex: 1;\n overflow: hidden;\n background: #525659;\n position: relative;\n padding: 0;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n.preview-html {\n width: 100%;\n height: 100%;\n overflow-y: auto;\n padding: 0.5rem 0.5rem;\n background: #525659;\n}\n.document-paper {\n background: #fff;\n max-width: 100%;\n margin: 0 auto;\n padding: 1rem 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n border-radius: 4px;\n}\n.preview-iframe,\n.preview-embed {\n width: 100%;\n height: 100%;\n border: none;\n display: block;\n flex: 1;\n min-height: 0;\n}\n.preview-loading,\n.preview-error {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n gap: 12px;\n}\n.error-title {\n font-size: 16px;\n font-weight: 600;\n color: #c00;\n}\n.error-message {\n font-size: 13px;\n color: #666;\n max-width: 400px;\n text-align: center;\n}\n.dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 2000;\n}\n.dialog-content {\n background: #fff;\n border-radius: 6px;\n max-width: 90vw;\n max-height: 90vh;\n overflow-y: auto;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\n}\n.dialog-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 16px;\n border-bottom: 1px solid #e5e7eb;\n}\n.dialog-header h3 {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n}\n.dialog-body {\n padding: 16px;\n}\n.dialog-footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 16px;\n border-top: 1px solid #e5e7eb;\n}\n.btn {\n padding: 7px 16px;\n border-radius: 4px;\n border: 1px solid #d0d0d0;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.12s;\n}\n.btn-primary {\n background: #0078d4;\n color: #fff;\n border-color: #0078d4;\n}\n.btn-primary:hover {\n background: #106ebe;\n}\n.btn-primary:disabled {\n opacity: 0.5;
2252\n cursor: not-allowed;\n}\n.btn-secondary {\n background: #f0f0f0;\n color: #151C28;\n}\n.btn-secondary:hover {\n background: #e0e0e0;\n}\n.btn-secondary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.confirm-dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 3000;\n}\n.confirm-dialog-content {\n background: #fff;\n border-radius: 8px;\n padding: 24px;\n max-width: 420px;\n width: 90%;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\n}\n.btn-professional {\n padding: 7px 16px;\n border-radius: 4px;\n border: 1px solid transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.12s;\n}\n.btn-outline {\n background: #f0f0f0;\n border-color: #d0d0d0;\n color: #151C28;\n}\n.btn-outline:hover {\n background: #e0e0e0;\n}\n.btn-danger {\n background: #d32f2f;\n color: #fff;\n border-color: #d32f2f;\n}\n.btn-danger:hover {\n background: #b71c1c;\n}\n.toast-notification {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 9999;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n min-width: 280px;\n}\n.toast-notification.success {\n background: #107c10;\n color: #fff;\n}\n.toast-notification.error {\n background: #d32f2f;\n color: #fff;\n}\n.toast-content {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n}\n.toast-message {\n flex: 1;\n font-size: 13px;\n}\n.toast-close {\n background: none;\n border: none;\n color: inherit;\n cursor: pointer;\n opacity: 0.8;\n font-size: 14px;\n}\n.toast-close:hover {\n opacity: 1;\n}\n.flex {\n display: flex;\n}\n.items-center {\n align-items: center;\n}\n.gap-2 {\n gap: 8px;\n}\n.gap-1 {\n gap: 4px;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-semibold {\n font-weight: 600;\n}\n.font-bold {\n font-weight: 700;\n}\n.text-sm {\n font-size: 13px;\n}\n.text-xs {\n font-size: 11px;\n}\n.truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.w-full {\n width: 100%;\n}\n.h-10 {\n height: 40px;\n}\n.px-3 {\n padding-left: 12px;\n padding-right: 12px;\n}\n.rounded-md {\n border-radius: 6px;\n}\n.border {\n border: 1px solid #d0d0d0;\n}\n.bg-background {\n background: #fff;\n}\n.space-y-4 > * + * {\n margin-top: 16px;\n}\n.space-y-2 > * + * {\n margin-top: 8px;\n}\n.space-y-1\\.5 > * + * {\n margin-top: 6px;\n}\n.hidden {\n display: none;\n}\n.max-h-32 {\n max-height: 128px;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.border-dashed {\n border-style: dashed;\n}\n.text-center {\n text-align: center;\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.p-2 {\n padding: 8px;\n}\n.p-8 {\n padding: 32px;\n}\n.text-muted-foreground {\n color: #6b7280;\n}\n.hover\\:text-foreground:hover {\n color: #151C28;\n}\n.text-lg {\n font-size: 18px;\n}\n.col-span-2 {\n grid-column: span 2;\n}\n/*# sourceMappingURL=rfp-documents.component-6FWKV3LY.css.map */\n'] }] 2253 }], () => [{ type: Router }, { type: ActivatedRoute }, { type: RfpService }, { type: DomSanitizer }, { type: HttpClient }, { type: Location }], { documentEditor: [{ 2254 type: ViewChild, 2255 args: ["documentEditor"] 2256 }], closeDropdownOnOutsideClick: [{ 2257 type: HostListener, 2258 args: ["document:click"] 2259 }] }); 2260})(); 2261(() => { 2262 (typeof ngDevMode === "undefined" || ngDevMode) && \u0275setClassDebugInfo(RfpDocumentsComponent, { className: "RfpDocumentsComponent", filePath: "src/app/pages/rfp-documents/rfp-documents.component.ts", lineNumber: 23 }); 2263})(); 2264export { 2265 RfpDocumentsComponent 2266}; 2267//# sourceMappingURL=chunk-AV2RH7TK.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.