@memberjunction/ng-explorer-core 5.43.0 → 5.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/generated/lazy-feature-config.d.ts +1 -1
  2. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  3. package/dist/generated/lazy-feature-config.js +11 -3
  4. package/dist/generated/lazy-feature-config.js.map +1 -1
  5. package/dist/lib/about/about-dialog.component.d.ts +0 -1
  6. package/dist/lib/about/about-dialog.component.d.ts.map +1 -1
  7. package/dist/lib/about/about-dialog.component.js +217 -218
  8. package/dist/lib/about/about-dialog.component.js.map +1 -1
  9. package/dist/lib/command-palette/command-palette.component.js +8 -14
  10. package/dist/lib/command-palette/command-palette.component.js.map +1 -1
  11. package/dist/lib/conversation-feedback/conversation-feedback.js +66 -73
  12. package/dist/lib/conversation-feedback/conversation-feedback.js.map +1 -1
  13. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +35 -45
  14. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
  15. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +2 -1
  16. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  17. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +14 -8
  18. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  19. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  20. package/dist/lib/resource-wrappers/dashboard-resource.component.js +9 -8
  21. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  22. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
  23. package/dist/lib/resource-wrappers/search-results-resource.component.js +35 -43
  24. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  25. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +10 -2
  26. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
  27. package/dist/lib/shell/components/tabs/component-cache-manager.js +19 -1
  28. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
  29. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +1 -0
  30. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  31. package/dist/lib/shell/components/tabs/tab-container.component.js +3 -2
  32. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  33. package/dist/lib/shell/shell.module.d.ts +1 -1
  34. package/dist/lib/shell/shell.module.d.ts.map +1 -1
  35. package/dist/lib/shell/shell.module.js +4 -1
  36. package/dist/lib/shell/shell.module.js.map +1 -1
  37. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +5 -7
  38. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
  39. package/dist/lib/single-dashboard/single-dashboard.component.js +17 -27
  40. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  41. package/dist/lib/single-list-detail/single-list-detail.component.d.ts +6 -2
  42. package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
  43. package/dist/lib/single-list-detail/single-list-detail.component.js +48 -57
  44. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  45. package/dist/lib/single-search-result/single-search-result.component.js +17 -22
  46. package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
  47. package/dist/lib/user-notifications/user-notifications.component.js +60 -75
  48. package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
  49. package/dist/module.d.ts +1 -1
  50. package/dist/module.d.ts.map +1 -1
  51. package/dist/module.js +12 -5
  52. package/dist/module.js.map +1 -1
  53. package/package.json +47 -47
  54. package/dist/lib/__tests__/explorer-core.test.d.ts +0 -2
  55. package/dist/lib/__tests__/explorer-core.test.d.ts.map +0 -1
  56. package/dist/lib/__tests__/explorer-core.test.js +0 -229
  57. package/dist/lib/__tests__/explorer-core.test.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"single-list-detail.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-list-detail/single-list-detail.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"single-list-detail.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-list-detail/single-list-detail.component.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { Component, Input, ViewChild, HostListener } from '@angular/core';
2
2
  import { CompositeKey, LogError, LogErrorEx, LogStatus, RunView } from '@memberjunction/core';
3
3
  import { GraphQLListsClient } from '@memberjunction/graphql-dataprovider';
4
4
  import { CapabilitiesForLevel } from '@memberjunction/lists-base';
5
- import { Subject, debounceTime } from 'rxjs';
5
+ import { Subject, debounceTime, takeUntil } from 'rxjs';
6
6
  import { UUIDsEqual, NormalizeUUID } from '@memberjunction/global';
7
7
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
8
8
  import * as i0 from "@angular/core";
@@ -315,17 +315,12 @@ function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_6_Te
315
315
  i0.ɵɵelementEnd();
316
316
  } }
317
317
  function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_7_Template(rf, ctx) { if (rf & 1) {
318
- i0.ɵɵelementStart(0, "div", 72);
319
- i0.ɵɵelement(1, "span", 75);
320
- i0.ɵɵelementStart(2, "p");
321
- i0.ɵɵtext(3, "No other lists found for this entity.");
322
- i0.ɵɵelementEnd();
323
- i0.ɵɵelementStart(4, "p", 76);
324
- i0.ɵɵtext(5, "Create a new list first if you need a new target.");
318
+ i0.ɵɵelementStart(0, "mj-empty-state", 72)(1, "p", 75);
319
+ i0.ɵɵtext(2, "Create a new list first if you need a new target.");
325
320
  i0.ɵɵelementEnd()();
326
321
  } }
327
322
  function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
328
- i0.ɵɵelementStart(0, "span", 82);
323
+ i0.ɵɵelementStart(0, "span", 81);
329
324
  i0.ɵɵtext(1);
330
325
  i0.ɵɵelementEnd();
331
326
  } if (rf & 2) {
@@ -335,15 +330,15 @@ function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_Fo
335
330
  } }
336
331
  function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
337
332
  const _r11 = i0.ɵɵgetCurrentView();
338
- i0.ɵɵelementStart(0, "div", 78);
333
+ i0.ɵɵelementStart(0, "div", 77);
339
334
  i0.ɵɵlistener("click", function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_For_2_Template_div_click_0_listener() { const target_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.selectMoveCopyTarget(target_r12)); });
340
- i0.ɵɵelementStart(1, "div", 79)(2, "input", 80);
335
+ i0.ɵɵelementStart(1, "div", 78)(2, "input", 79);
341
336
  i0.ɵɵlistener("click", function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_For_2_Template_input_click_2_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); })("change", function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_For_2_Template_input_change_2_listener() { const target_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.selectMoveCopyTarget(target_r12)); });
342
337
  i0.ɵɵelementEnd()();
343
- i0.ɵɵelementStart(3, "div", 81)(4, "strong");
338
+ i0.ɵɵelementStart(3, "div", 80)(4, "strong");
344
339
  i0.ɵɵtext(5);
345
340
  i0.ɵɵelementEnd();
346
- i0.ɵɵconditionalCreate(6, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_For_2_Conditional_6_Template, 2, 1, "span", 82);
341
+ i0.ɵɵconditionalCreate(6, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_For_2_Conditional_6_Template, 2, 1, "span", 81);
347
342
  i0.ɵɵelementEnd()();
348
343
  } if (rf & 2) {
349
344
  const target_r12 = ctx.$implicit;
@@ -358,7 +353,7 @@ function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_Fo
358
353
  } }
359
354
  function SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_Template(rf, ctx) { if (rf & 1) {
360
355
  i0.ɵɵelementStart(0, "div", 73);
361
- i0.ɵɵrepeaterCreate(1, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_For_2_Template, 7, 5, "div", 77, _forTrack1);
356
+ i0.ɵɵrepeaterCreate(1, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_For_2_Template, 7, 5, "div", 76, _forTrack1);
362
357
  i0.ɵɵelementEnd();
363
358
  } if (rf & 2) {
364
359
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -375,7 +370,7 @@ function SingleListDetailComponent_Conditional_14_Conditional_3_Template(rf, ctx
375
370
  i0.ɵɵelementStart(5, "input", 70);
376
371
  i0.ɵɵtwoWayListener("ngModelChange", function SingleListDetailComponent_Conditional_14_Conditional_3_Template_input_ngModelChange_5_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r0.moveCopyTargetSearch, $event) || (ctx_r0.moveCopyTargetSearch = $event); return i0.ɵɵresetView($event); });
377
372
  i0.ɵɵelementEnd()()();
378
- i0.ɵɵconditionalCreate(6, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_6_Template, 2, 0, "div", 71)(7, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_7_Template, 6, 0, "div", 72)(8, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_Template, 3, 0, "div", 73);
373
+ i0.ɵɵconditionalCreate(6, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_6_Template, 2, 0, "div", 71)(7, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_7_Template, 3, 0, "mj-empty-state", 72)(8, SingleListDetailComponent_Conditional_14_Conditional_3_Conditional_8_Template, 3, 0, "div", 73);
379
374
  } if (rf & 2) {
380
375
  const ctx_r0 = i0.ɵɵnextContext(2);
381
376
  i0.ɵɵadvance();
@@ -432,7 +427,7 @@ function SingleListDetailComponent_Conditional_15_Conditional_2_Conditional_2_Te
432
427
  } }
433
428
  function SingleListDetailComponent_Conditional_15_Conditional_2_Template(rf, ctx) { if (rf & 1) {
434
429
  i0.ɵɵelementStart(0, "div", 61);
435
- i0.ɵɵelement(1, "mj-loading", 87);
430
+ i0.ɵɵelement(1, "mj-loading", 86);
436
431
  i0.ɵɵconditionalCreate(2, SingleListDetailComponent_Conditional_15_Conditional_2_Conditional_2_Template, 1, 1, "mj-progress-bar", 65);
437
432
  i0.ɵɵelementEnd();
438
433
  } if (rf & 2) {
@@ -441,8 +436,8 @@ function SingleListDetailComponent_Conditional_15_Conditional_2_Template(rf, ctx
441
436
  i0.ɵɵconditional(ctx_r0.removeTotal > 0 ? 2 : -1);
442
437
  } }
443
438
  function SingleListDetailComponent_Conditional_15_Conditional_3_Template(rf, ctx) { if (rf & 1) {
444
- i0.ɵɵelementStart(0, "div", 85);
445
- i0.ɵɵelement(1, "span", 88);
439
+ i0.ɵɵelementStart(0, "div", 84);
440
+ i0.ɵɵelement(1, "span", 87);
446
441
  i0.ɵɵelementStart(2, "p");
447
442
  i0.ɵɵtext(3, "Are you sure you want to remove ");
448
443
  i0.ɵɵelementStart(4, "strong");
@@ -450,7 +445,7 @@ function SingleListDetailComponent_Conditional_15_Conditional_3_Template(rf, ctx
450
445
  i0.ɵɵelementEnd();
451
446
  i0.ɵɵtext(6);
452
447
  i0.ɵɵelementEnd();
453
- i0.ɵɵelementStart(7, "p", 76);
448
+ i0.ɵɵelementStart(7, "p", 75);
454
449
  i0.ɵɵtext(8, "This will not delete the records, only remove them from this list.");
455
450
  i0.ɵɵelementEnd()();
456
451
  } if (rf & 2) {
@@ -462,12 +457,12 @@ function SingleListDetailComponent_Conditional_15_Conditional_3_Template(rf, ctx
462
457
  } }
463
458
  function SingleListDetailComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
464
459
  const _r13 = i0.ɵɵgetCurrentView();
465
- i0.ɵɵelementStart(0, "mj-dialog", 83);
460
+ i0.ɵɵelementStart(0, "mj-dialog", 82);
466
461
  i0.ɵɵlistener("Close", function SingleListDetailComponent_Conditional_15_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeRemoveDialog()); });
467
- i0.ɵɵelementStart(1, "div", 84);
468
- i0.ɵɵconditionalCreate(2, SingleListDetailComponent_Conditional_15_Conditional_2_Template, 3, 1, "div", 61)(3, SingleListDetailComponent_Conditional_15_Conditional_3_Template, 9, 2, "div", 85);
462
+ i0.ɵɵelementStart(1, "div", 83);
463
+ i0.ɵɵconditionalCreate(2, SingleListDetailComponent_Conditional_15_Conditional_2_Template, 3, 1, "div", 61)(3, SingleListDetailComponent_Conditional_15_Conditional_3_Template, 9, 2, "div", 84);
469
464
  i0.ɵɵelementEnd();
470
- i0.ɵɵelementStart(4, "mj-dialog-actions")(5, "button", 86);
465
+ i0.ɵɵelementStart(4, "mj-dialog-actions")(5, "button", 85);
471
466
  i0.ɵɵlistener("click", function SingleListDetailComponent_Conditional_15_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.confirmRemoveFromList()); });
472
467
  i0.ɵɵtext(6, " Remove ");
473
468
  i0.ɵɵelementEnd();
@@ -493,7 +488,7 @@ function SingleListDetailComponent_Conditional_16_Conditional_2_Conditional_2_Te
493
488
  } }
494
489
  function SingleListDetailComponent_Conditional_16_Conditional_2_Template(rf, ctx) { if (rf & 1) {
495
490
  i0.ɵɵelementStart(0, "div", 61);
496
- i0.ɵɵelement(1, "mj-loading", 90);
491
+ i0.ɵɵelement(1, "mj-loading", 89);
497
492
  i0.ɵɵconditionalCreate(2, SingleListDetailComponent_Conditional_16_Conditional_2_Conditional_2_Template, 1, 1, "mj-progress-bar", 65);
498
493
  i0.ɵɵelementEnd();
499
494
  } if (rf & 2) {
@@ -503,29 +498,20 @@ function SingleListDetailComponent_Conditional_16_Conditional_2_Template(rf, ctx
503
498
  } }
504
499
  function SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_7_Template(rf, ctx) { if (rf & 1) {
505
500
  i0.ɵɵelementStart(0, "div", 71);
506
- i0.ɵɵelement(1, "mj-loading", 94);
501
+ i0.ɵɵelement(1, "mj-loading", 95);
507
502
  i0.ɵɵelementEnd();
508
503
  } if (rf & 2) {
509
504
  i0.ɵɵadvance();
510
505
  i0.ɵɵproperty("showText", false);
511
506
  } }
512
507
  function SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_8_Template(rf, ctx) { if (rf & 1) {
513
- i0.ɵɵelementStart(0, "div", 72);
514
- i0.ɵɵelement(1, "span", 95);
515
- i0.ɵɵelementStart(2, "p");
516
- i0.ɵɵtext(3);
517
- i0.ɵɵelementEnd()();
508
+ i0.ɵɵelement(0, "mj-empty-state", 93);
518
509
  } if (rf & 2) {
519
510
  const ctx_r0 = i0.ɵɵnextContext(3);
520
- i0.ɵɵadvance(3);
521
- i0.ɵɵtextInterpolate1("No records found matching \"", ctx_r0.addRecordsSearchFilter, "\"");
511
+ i0.ɵɵproperty("Title", ctx_r0.AddRecordsNoMatchTitle);
522
512
  } }
523
513
  function SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_9_Template(rf, ctx) { if (rf & 1) {
524
- i0.ɵɵelementStart(0, "div", 72);
525
- i0.ɵɵelement(1, "span", 75);
526
- i0.ɵɵelementStart(2, "p");
527
- i0.ɵɵtext(3, "Search for records to add to this list");
528
- i0.ɵɵelementEnd()();
514
+ i0.ɵɵelement(0, "mj-empty-state", 94);
529
515
  } }
530
516
  function SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_10_For_9_Conditional_2_Template(rf, ctx) { if (rf & 1) {
531
517
  i0.ɵɵelement(0, "span", 101);
@@ -546,12 +532,12 @@ function SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_10_F
546
532
  } }
547
533
  function SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_10_For_9_Template(rf, ctx) { if (rf & 1) {
548
534
  const _r17 = i0.ɵɵgetCurrentView();
549
- i0.ɵɵelementStart(0, "div", 78);
535
+ i0.ɵɵelementStart(0, "div", 77);
550
536
  i0.ɵɵlistener("click", function SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_10_For_9_Template_div_click_0_listener() { const record_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleRecordSelection(record_r18)); });
551
- i0.ɵɵelementStart(1, "div", 79);
537
+ i0.ɵɵelementStart(1, "div", 78);
552
538
  i0.ɵɵconditionalCreate(2, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_10_For_9_Conditional_2_Template, 1, 0, "span", 101)(3, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_10_For_9_Conditional_3_Template, 1, 1, "input", 102);
553
539
  i0.ɵɵelementEnd();
554
- i0.ɵɵelementStart(4, "div", 81);
540
+ i0.ɵɵelementStart(4, "div", 80);
555
541
  i0.ɵɵtext(5);
556
542
  i0.ɵɵelementEnd();
557
543
  i0.ɵɵconditionalCreate(6, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_10_For_9_Conditional_6_Template, 2, 0, "span", 103);
@@ -593,14 +579,14 @@ function SingleListDetailComponent_Conditional_16_Conditional_3_Template(rf, ctx
593
579
  const _r15 = i0.ɵɵgetCurrentView();
594
580
  i0.ɵɵelementStart(0, "div", 67)(1, "div", 68);
595
581
  i0.ɵɵelement(2, "span", 69);
596
- i0.ɵɵelementStart(3, "input", 91);
582
+ i0.ɵɵelementStart(3, "input", 90);
597
583
  i0.ɵɵlistener("input", function SingleListDetailComponent_Conditional_16_Conditional_3_Template_input_input_3_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onAddRecordsSearchInputEvent($event)); });
598
584
  i0.ɵɵelementEnd()();
599
- i0.ɵɵelementStart(4, "span", 92);
585
+ i0.ɵɵelementStart(4, "span", 91);
600
586
  i0.ɵɵtext(5, "Type at least 2 characters to search");
601
587
  i0.ɵɵelementEnd()();
602
- i0.ɵɵelementStart(6, "div", 93);
603
- i0.ɵɵconditionalCreate(7, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_7_Template, 2, 1, "div", 71)(8, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_8_Template, 4, 1, "div", 72)(9, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_9_Template, 4, 0, "div", 72)(10, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_10_Template, 10, 1);
588
+ i0.ɵɵelementStart(6, "div", 92);
589
+ i0.ɵɵconditionalCreate(7, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_7_Template, 2, 1, "div", 71)(8, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_8_Template, 1, 1, "mj-empty-state", 93)(9, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_9_Template, 1, 0, "mj-empty-state", 94)(10, SingleListDetailComponent_Conditional_16_Conditional_3_Conditional_10_Template, 10, 1);
604
590
  i0.ɵɵelementEnd();
605
591
  } if (rf & 2) {
606
592
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -613,7 +599,7 @@ function SingleListDetailComponent_Conditional_16_Template(rf, ctx) { if (rf & 1
613
599
  const _r14 = i0.ɵɵgetCurrentView();
614
600
  i0.ɵɵelementStart(0, "mj-dialog", 59);
615
601
  i0.ɵɵlistener("Close", function SingleListDetailComponent_Conditional_16_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddRecordsDialog()); });
616
- i0.ɵɵelementStart(1, "div", 89);
602
+ i0.ɵɵelementStart(1, "div", 88);
617
603
  i0.ɵɵconditionalCreate(2, SingleListDetailComponent_Conditional_16_Conditional_2_Template, 3, 1, "div", 61)(3, SingleListDetailComponent_Conditional_16_Conditional_3_Template, 11, 3);
618
604
  i0.ɵɵelementEnd();
619
605
  i0.ɵɵelementStart(4, "mj-dialog-actions")(5, "button", 62);
@@ -756,7 +742,7 @@ function SingleListDetailComponent_Conditional_18_Conditional_2_Template(rf, ctx
756
742
  } }
757
743
  function SingleListDetailComponent_Conditional_18_Conditional_3_Template(rf, ctx) { if (rf & 1) {
758
744
  i0.ɵɵelementStart(0, "div", 61);
759
- i0.ɵɵelement(1, "mj-loading", 90)(2, "mj-progress-bar", 65);
745
+ i0.ɵɵelement(1, "mj-loading", 89)(2, "mj-progress-bar", 65);
760
746
  i0.ɵɵelementEnd();
761
747
  } if (rf & 2) {
762
748
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -769,11 +755,7 @@ function SingleListDetailComponent_Conditional_18_Conditional_4_Template(rf, ctx
769
755
  i0.ɵɵelementEnd();
770
756
  } }
771
757
  function SingleListDetailComponent_Conditional_18_Conditional_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
772
- i0.ɵɵelementStart(0, "div", 72);
773
- i0.ɵɵelement(1, "span", 127);
774
- i0.ɵɵelementStart(2, "p");
775
- i0.ɵɵtext(3, "No saved views found for this entity");
776
- i0.ɵɵelementEnd()();
758
+ i0.ɵɵelement(0, "mj-empty-state", 127);
777
759
  } }
778
760
  function SingleListDetailComponent_Conditional_18_Conditional_5_Conditional_4_For_1_Template(rf, ctx) { if (rf & 1) {
779
761
  const _r24 = i0.ɵɵgetCurrentView();
@@ -806,7 +788,7 @@ function SingleListDetailComponent_Conditional_18_Conditional_5_Template(rf, ctx
806
788
  i0.ɵɵtext(1, "Select views to add their records to this list:");
807
789
  i0.ɵɵelementEnd();
808
790
  i0.ɵɵelementStart(2, "div", 126);
809
- i0.ɵɵconditionalCreate(3, SingleListDetailComponent_Conditional_18_Conditional_5_Conditional_3_Template, 4, 0, "div", 72)(4, SingleListDetailComponent_Conditional_18_Conditional_5_Conditional_4_Template, 2, 0);
791
+ i0.ɵɵconditionalCreate(3, SingleListDetailComponent_Conditional_18_Conditional_5_Conditional_3_Template, 1, 0, "mj-empty-state", 127)(4, SingleListDetailComponent_Conditional_18_Conditional_5_Conditional_4_Template, 2, 0);
810
792
  i0.ɵɵelementEnd();
811
793
  } if (rf & 2) {
812
794
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -817,7 +799,7 @@ function SingleListDetailComponent_Conditional_18_Template(rf, ctx) { if (rf & 1
817
799
  const _r23 = i0.ɵɵgetCurrentView();
818
800
  i0.ɵɵelementStart(0, "mj-dialog", 123);
819
801
  i0.ɵɵlistener("Close", function SingleListDetailComponent_Conditional_18_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddFromViewDialog()); });
820
- i0.ɵɵelementStart(1, "div", 84);
802
+ i0.ɵɵelementStart(1, "div", 83);
821
803
  i0.ɵɵconditionalCreate(2, SingleListDetailComponent_Conditional_18_Conditional_2_Template, 2, 0, "div", 61)(3, SingleListDetailComponent_Conditional_18_Conditional_3_Template, 3, 1, "div", 61)(4, SingleListDetailComponent_Conditional_18_Conditional_4_Template, 2, 0, "div", 61)(5, SingleListDetailComponent_Conditional_18_Conditional_5_Template, 5, 1);
822
804
  i0.ɵɵelementEnd();
823
805
  i0.ɵɵelementStart(6, "mj-dialog-actions")(7, "button", 62);
@@ -930,10 +912,15 @@ export class SingleListDetailComponent extends BaseAngularComponent {
930
912
  addDialogSaving = false;
931
913
  addableRecords = [];
932
914
  addRecordsSearchFilter = "";
915
+ /** Empty-state title shown when an add-records search returns no matches. */
916
+ get AddRecordsNoMatchTitle() {
917
+ return `No records found matching "${this.addRecordsSearchFilter}"`;
918
+ }
933
919
  existingListDetailIds = new Set();
934
920
  addProgress = 0;
935
921
  addTotal = 0;
936
922
  searchSubject = new Subject();
923
+ destroy$ = new Subject();
937
924
  // Add from view dialog (existing)
938
925
  showAddFromViewDialog = false;
939
926
  showAddFromViewLoader = false;
@@ -991,9 +978,13 @@ export class SingleListDetailComponent extends BaseAngularComponent {
991
978
  this.listSharingService = listSharingService;
992
979
  // Debounce search input
993
980
  this.searchSubject
994
- .pipe(debounceTime(300))
981
+ .pipe(debounceTime(300), takeUntil(this.destroy$))
995
982
  .subscribe((searchText) => this.searchRecords(searchText));
996
983
  }
984
+ ngOnDestroy() {
985
+ this.destroy$.next();
986
+ this.destroy$.complete();
987
+ }
997
988
  ngOnInit() {
998
989
  if (this.ListID) {
999
990
  // Defer the load to a macrotask so the initial assignment of
@@ -2116,7 +2107,7 @@ export class SingleListDetailComponent extends BaseAngularComponent {
2116
2107
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.listDetailGrid = _t.first);
2117
2108
  } }, hostBindings: function SingleListDetailComponent_HostBindings(rf, ctx) { if (rf & 1) {
2118
2109
  i0.ɵɵlistener("click", function SingleListDetailComponent_click_HostBindingHandler($event) { return ctx.onDocumentClick($event); }, i0.ɵɵresolveDocument);
2119
- } }, inputs: { ListID: "ListID" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 19, vars: 20, consts: [["listDetailGrid", ""], [1, "list-detail-container"], [1, "list-header"], [1, "list-header__titleblock"], [1, "lineage-badge", 3, "title"], [1, "list-detail__tags"], [1, "add-dropdown-wrapper"], [1, "permission-badge", "permission-badge--viewer"], [1, "custom-toolbar"], [1, "loading-container"], [1, "grid-with-stats"], [3, "Confirm", "Cancel", "Visible", "Delta", "TargetListName", "SourceLabel"], [3, "Visible", "Title", "MinWidth", "Width", "Height"], ["Title", "Remove from List", 3, "Visible", "MinWidth", "Width"], ["Title", "Add Records from Views", 3, "Visible", "MinWidth", "Width", "Height"], [1, "fa-solid", "fa-link"], [1, "lineage-badge__refreshed"], ["EntityName", "MJ: Lists", 3, "Provider", "RecordID", "Editable", "MaxDisplay"], ["mjButton", "", "variant", "primary", 1, "add-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fa-solid", "fa-chevron-down", "add-dropdown-arrow"], [1, "add-dropdown-panel"], [1, "add-dropdown-item"], [1, "add-dropdown-item", 3, "click"], [1, "add-dropdown-item-text"], [1, "add-dropdown-item-desc"], [1, "fa-solid", "fa-eye"], [1, "toolbar-left"], [1, "row-count"], [1, "selection-count"], [1, "toolbar-right"], ["mjButton", "", "variant", "flat", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-rotate"], [1, "fa-solid", "fa-file-export"], ["mjButton", "", "variant", "flat", "title", "Move selected records to another list", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-arrow-right-arrow-left"], ["mjButton", "", "variant", "flat", "title", "Copy selected records to another list (keeps them here too)", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-copy"], ["title", "Set status on selected items", 1, "mj-input", "mj-select", "bulk-status-select", 3, "ngModelChange", "ngModel", "disabled"], ["value", ""], ["value", "Active"], ["value", "Complete"], ["value", "Pending"], ["value", "Disabled"], ["value", "Rejected"], ["mjButton", "", "variant", "flat", 1, "toolbar-button", 3, "click", "disabled"], ["mjButton", "", "variant", "flat", 1, "toolbar-button", "remove-btn", 3, "click"], [1, "fa-solid", "fa-trash"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-pen-to-square"], ["title", "Refresh mode", 1, "mj-input", "mj-select", "refresh-mode-select", 3, "ngModelChange", "ngModel", "disabled"], ["value", "Additive"], ["value", "Sync"], [1, "fa-solid", "fa-cloud-arrow-down"], ["text", "Loading list...", "size", "medium"], [1, "grid-container"], [3, "rowClicked", "rowDoubleClicked", "selectionChange", "dataLoaded", "listId", "listEntity", "autoNavigate", "height", "showToolbar", "toolbarConfig", "selectionMode"], [1, "list-detail__stats"], [3, "Provider", "ListID", "RefreshTrigger"], [3, "Close", "Visible", "Title", "MinWidth", "Width", "Height"], [1, "dialog-content", "move-copy-dialog"], [1, "dialog-loading"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", "variant", "outline", 3, "click", "disabled"], ["size", "small", 3, "text"], [1, "progress-bar", 3, "Value"], [1, "dialog-instruction"], [1, "search-section"], [1, "search-input-wrapper"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Filter lists by name\u2026", 1, "mj-input", "search-input", 3, "ngModelChange", "ngModel"], [1, "list-loading"], [1, "empty-results"], [1, "records-scroll", "move-copy-targets"], ["text", "Loading lists...", "size", "small"], [1, "fa-solid", "fa-list", "empty-icon"], [1, "dialog-note"], [1, "record-item", 3, "selected"], [1, "record-item", 3, "click"], [1, "record-checkbox"], ["type", "radio", "name", "moveCopyTarget", 3, "click", "change", "checked"], [1, "record-name"], [1, "target-desc"], ["Title", "Remove from List", 3, "Close", "Visible", "MinWidth", "Width"], [1, "dialog-content"], [1, "dialog-message"], ["mjButton", "", "variant", "danger", 3, "click", "disabled"], ["text", "Removing records...", "size", "small"], [1, "fa-solid", "fa-triangle-exclamation", "warning-icon"], [1, "dialog-content", "add-records-dialog"], ["text", "Adding records to list...", "size", "small"], ["type", "text", 1, "mj-input", "search-input", 3, "input", "placeholder", "value"], [1, "search-hint"], [1, "records-list"], ["size", "small", 3, "showText"], [1, "fa-solid", "fa-search", "empty-icon"], [1, "selection-controls"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click"], [1, "selection-info"], [1, "records-scroll"], [1, "record-item", 3, "in-list", "selected"], ["title", "Already in list", 1, "fa-solid", "fa-check", "in-list-icon"], ["type", "checkbox", 3, "checked"], [1, "in-list-badge"], ["type", "checkbox", 3, "click", "change", "checked"], [1, "dialog-content", "export-dialog"], [1, "export-section-label"], [1, "export-format-row"], [1, "export-format-option", 3, "click"], ["type", "radio", "name", "exportFormat", "value", "excel", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-file-excel", 2, "color", "var(--mj-status-success)"], ["type", "radio", "name", "exportFormat", "value", "csv", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-file-csv", 2, "color", "var(--mj-text-secondary)"], ["type", "radio", "name", "exportFormat", "value", "json", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-file-code", 2, "color", "var(--mj-brand-primary)"], [1, "export-section-divider"], [1, "export-fields-list"], [1, "export-field-row"], [1, "export-field-actions"], ["href", "#", 3, "click"], [1, "muted"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-download"], ["Title", "Add Records from Views", 3, "Close", "Visible", "MinWidth", "Width", "Height"], ["text", "Loading records from views...", "size", "small"], ["text", "Loading views...", "size", "small"], [1, "views-list"], [1, "fa-solid", "fa-folder-open", "empty-icon"], [1, "view-item", 3, "selected"], [1, "view-item", 3, "click"], [1, "fa-solid", "fa-table-list", "view-icon"], [1, "view-name"]], template: function SingleListDetailComponent_Template(rf, ctx) { if (rf & 1) {
2110
+ } }, inputs: { ListID: "ListID" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 19, vars: 20, consts: [["listDetailGrid", ""], [1, "list-detail-container"], [1, "list-header"], [1, "list-header__titleblock"], [1, "lineage-badge", 3, "title"], [1, "list-detail__tags"], [1, "add-dropdown-wrapper"], [1, "permission-badge", "permission-badge--viewer"], [1, "custom-toolbar"], [1, "loading-container"], [1, "grid-with-stats"], [3, "Confirm", "Cancel", "Visible", "Delta", "TargetListName", "SourceLabel"], [3, "Visible", "Title", "MinWidth", "Width", "Height"], ["Title", "Remove from List", 3, "Visible", "MinWidth", "Width"], ["Title", "Add Records from Views", 3, "Visible", "MinWidth", "Width", "Height"], [1, "fa-solid", "fa-link"], [1, "lineage-badge__refreshed"], ["EntityName", "MJ: Lists", 3, "Provider", "RecordID", "Editable", "MaxDisplay"], ["mjButton", "", "variant", "primary", 1, "add-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fa-solid", "fa-chevron-down", "add-dropdown-arrow"], [1, "add-dropdown-panel"], [1, "add-dropdown-item"], [1, "add-dropdown-item", 3, "click"], [1, "add-dropdown-item-text"], [1, "add-dropdown-item-desc"], [1, "fa-solid", "fa-eye"], [1, "toolbar-left"], [1, "row-count"], [1, "selection-count"], [1, "toolbar-right"], ["mjButton", "", "variant", "flat", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-rotate"], [1, "fa-solid", "fa-file-export"], ["mjButton", "", "variant", "flat", "title", "Move selected records to another list", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-arrow-right-arrow-left"], ["mjButton", "", "variant", "flat", "title", "Copy selected records to another list (keeps them here too)", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-copy"], ["title", "Set status on selected items", 1, "mj-input", "mj-select", "bulk-status-select", 3, "ngModelChange", "ngModel", "disabled"], ["value", ""], ["value", "Active"], ["value", "Complete"], ["value", "Pending"], ["value", "Disabled"], ["value", "Rejected"], ["mjButton", "", "variant", "flat", 1, "toolbar-button", 3, "click", "disabled"], ["mjButton", "", "variant", "flat", 1, "toolbar-button", "remove-btn", 3, "click"], [1, "fa-solid", "fa-trash"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-pen-to-square"], ["title", "Refresh mode", 1, "mj-input", "mj-select", "refresh-mode-select", 3, "ngModelChange", "ngModel", "disabled"], ["value", "Additive"], ["value", "Sync"], [1, "fa-solid", "fa-cloud-arrow-down"], ["text", "Loading list...", "size", "medium"], [1, "grid-container"], [3, "rowClicked", "rowDoubleClicked", "selectionChange", "dataLoaded", "listId", "listEntity", "autoNavigate", "height", "showToolbar", "toolbarConfig", "selectionMode"], [1, "list-detail__stats"], [3, "Provider", "ListID", "RefreshTrigger"], [3, "Close", "Visible", "Title", "MinWidth", "Width", "Height"], [1, "dialog-content", "move-copy-dialog"], [1, "dialog-loading"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", "variant", "outline", 3, "click", "disabled"], ["size", "small", 3, "text"], [1, "progress-bar", 3, "Value"], [1, "dialog-instruction"], [1, "search-section"], [1, "search-input-wrapper"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Filter lists by name\u2026", 1, "mj-input", "search-input", 3, "ngModelChange", "ngModel"], [1, "list-loading"], ["Size", "compact", "Icon", "fa-solid fa-list", "Title", "No other lists found for this entity."], [1, "records-scroll", "move-copy-targets"], ["text", "Loading lists...", "size", "small"], [1, "dialog-note"], [1, "record-item", 3, "selected"], [1, "record-item", 3, "click"], [1, "record-checkbox"], ["type", "radio", "name", "moveCopyTarget", 3, "click", "change", "checked"], [1, "record-name"], [1, "target-desc"], ["Title", "Remove from List", 3, "Close", "Visible", "MinWidth", "Width"], [1, "dialog-content"], [1, "dialog-message"], ["mjButton", "", "variant", "danger", 3, "click", "disabled"], ["text", "Removing records...", "size", "small"], [1, "fa-solid", "fa-triangle-exclamation", "warning-icon"], [1, "dialog-content", "add-records-dialog"], ["text", "Adding records to list...", "size", "small"], ["type", "text", 1, "mj-input", "search-input", 3, "input", "placeholder", "value"], [1, "search-hint"], [1, "records-list"], ["Variant", "no-results", "Size", "compact", "Icon", "fa-solid fa-magnifying-glass", 3, "Title"], ["Size", "compact", "Icon", "fa-solid fa-list", "Title", "Search for records to add to this list"], ["size", "small", 3, "showText"], [1, "selection-controls"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click"], [1, "selection-info"], [1, "records-scroll"], [1, "record-item", 3, "in-list", "selected"], ["title", "Already in list", 1, "fa-solid", "fa-check", "in-list-icon"], ["type", "checkbox", 3, "checked"], [1, "in-list-badge"], ["type", "checkbox", 3, "click", "change", "checked"], [1, "dialog-content", "export-dialog"], [1, "export-section-label"], [1, "export-format-row"], [1, "export-format-option", 3, "click"], ["type", "radio", "name", "exportFormat", "value", "excel", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-file-excel", 2, "color", "var(--mj-status-success)"], ["type", "radio", "name", "exportFormat", "value", "csv", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-file-csv", 2, "color", "var(--mj-text-secondary)"], ["type", "radio", "name", "exportFormat", "value", "json", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-file-code", 2, "color", "var(--mj-brand-primary)"], [1, "export-section-divider"], [1, "export-fields-list"], [1, "export-field-row"], [1, "export-field-actions"], ["href", "#", 3, "click"], [1, "muted"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-download"], ["Title", "Add Records from Views", 3, "Close", "Visible", "MinWidth", "Width", "Height"], ["text", "Loading records from views...", "size", "small"], ["text", "Loading views...", "size", "small"], [1, "views-list"], ["Size", "compact", "Icon", "fa-solid fa-folder-open", "Title", "No saved views found for this entity"], [1, "view-item", 3, "selected"], [1, "view-item", 3, "click"], [1, "fa-solid", "fa-table-list", "view-icon"], [1, "view-name"]], template: function SingleListDetailComponent_Template(rf, ctx) { if (rf & 1) {
2120
2111
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "div", 3);
2121
2112
  i0.ɵɵconditionalCreate(3, SingleListDetailComponent_Conditional_3_Template, 2, 1, "h1")(4, SingleListDetailComponent_Conditional_4_Template, 2, 0, "h1");
2122
2113
  i0.ɵɵconditionalCreate(5, SingleListDetailComponent_Conditional_5_Template, 6, 3, "div", 4);
@@ -2167,11 +2158,11 @@ export class SingleListDetailComponent extends BaseAngularComponent {
2167
2158
  i0.ɵɵconditional(ctx.showExportDialog && ctx.listRecord ? 17 : -1);
2168
2159
  i0.ɵɵadvance();
2169
2160
  i0.ɵɵconditional(ctx.showAddFromViewDialog ? 18 : -1);
2170
- } }, dependencies: [i4.NgSelectOption, i4.ɵNgSelectMultipleOption, i4.DefaultValueAccessor, i4.CheckboxControlValueAccessor, i4.SelectControlValueAccessor, i4.RadioControlValueAccessor, i4.NgControlStatus, i4.NgModel, i5.MJProgressBarComponent, i6.LoadingComponent, i7.ListDetailGridComponent, i3.ListDeltaConfirmComponent, i3.ListStatsComponent, i3.TagChipsComponent, i5.MJButtonDirective, i5.MJDialogComponent, i5.MJDialogActionsComponent, i8.DatePipe], styles: [".list-detail-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n}\n\n.list-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 16px;\n flex-shrink: 0;\n gap: 16px;\n}\n\n.list-header__titleblock[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n\n.list-header[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.lineage-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n color: var(--mj-text-secondary);\n font-size: 12px;\n width: fit-content;\n}\n\n.lineage-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.lineage-badge__refreshed[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.refresh-mode-select[_ngcontent-%COMP%] {\n min-width: 100px;\n font-size: 13px;\n}\n\n.bulk-status-select[_ngcontent-%COMP%] {\n min-width: 130px;\n font-size: 13px;\n}\n\n\n\n\n\n.permission-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.permission-badge--viewer[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n.list-detail__tags[_ngcontent-%COMP%] {\n margin-top: 8px;\n}\n\n\n\n\n.grid-with-stats[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 280px;\n gap: 16px;\n flex: 1;\n min-height: 0;\n}\n\n.list-detail__stats[_ngcontent-%COMP%] {\n min-width: 0;\n overflow-y: auto;\n}\n\n@media (max-width: 900px) {\n .grid-with-stats[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .list-detail__stats[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n.custom-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-bottom: none;\n border-radius: 8px 8px 0 0;\n flex-shrink: 0;\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.selection-count[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n}\n\n.toolbar-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.remove-btn[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.grid-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 0 0 8px 8px;\n overflow: hidden;\n}\n\n\n\n.add-dropdown-wrapper[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.add-btn[_ngcontent-%COMP%] {\n font-size: 16px;\n padding: 8px 25px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.add-dropdown-arrow[_ngcontent-%COMP%] {\n font-size: 12px;\n margin-left: 4px;\n}\n\n.add-dropdown-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 240px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);\n z-index: 100;\n overflow: hidden;\n}\n\n.add-dropdown-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 10px 16px;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n\n.add-dropdown-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.add-dropdown-item-text[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.add-dropdown-item-desc[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n\n\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 8px 0;\n}\n\n.dialog-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n gap: 20px;\n}\n\n.dialog-message[_ngcontent-%COMP%] {\n text-align: center;\n padding: 20px;\n}\n\n.warning-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-status-warning);\n margin-bottom: 16px;\n display: block;\n}\n\n.dialog-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 8px 0;\n font-size: 15px;\n color: var(--mj-text-primary);\n}\n\n.dialog-note[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary) !important;\n font-size: 13px !important;\n}\n\n.progress-bar[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 300px;\n}\n\n\n\n\n\n\n.add-records-dialog[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.search-section[_ngcontent-%COMP%] {\n padding-bottom: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 12px;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] .search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 14px;\n pointer-events: none;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] .search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding-left: 32px;\n}\n\n.search-hint[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n.records-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.list-loading[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 40px;\n}\n\n.empty-results[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n color: var(--mj-border-strong);\n}\n\n.empty-results[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n.selection-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 8px;\n}\n\n.selection-info[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.records-scroll[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n max-height: 280px;\n}\n\n.record-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.record-item[_ngcontent-%COMP%]:hover:not(.in-list) {\n background: var(--mj-bg-surface-card);\n}\n\n.record-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.record-item.in-list[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n cursor: default;\n opacity: 0.7;\n}\n\n.record-checkbox[_ngcontent-%COMP%] {\n width: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.record-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.in-list-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n.record-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.in-list-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-radius: 10px;\n font-weight: 500;\n}\n\n\n\n\n\n\n.dialog-instruction[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.views-list[_ngcontent-%COMP%] {\n max-height: 320px;\n overflow-y: auto;\n}\n\n.view-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.view-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.view-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.view-item[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.view-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.view-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n\n\n.export-dialog[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 8px; }\n.export-section-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n margin-bottom: 8px;\n}\n.export-format-row[_ngcontent-%COMP%] { display: flex; gap: 8px; }\n.export-format-option[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 13px;\n background: var(--mj-bg-surface);\n}\n.export-format-option--selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n.export-format-option[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] { margin: 0; }\n.export-section-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 16px 0;\n}\n.export-fields-list[_ngcontent-%COMP%] {\n max-height: 280px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n.export-field-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 13px;\n cursor: pointer;\n}\n.export-field-row[_ngcontent-%COMP%]:last-child { border-bottom: none; }\n.export-field-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.export-field-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n align-items: center;\n font-size: 11.5px;\n}\n.export-field-actions[_ngcontent-%COMP%] a[_ngcontent-%COMP%] { color: var(--mj-text-link); }\n.export-field-actions[_ngcontent-%COMP%] .muted[_ngcontent-%COMP%] {\n margin-left: auto;\n color: var(--mj-text-muted);\n}"] });
2161
+ } }, dependencies: [i4.NgSelectOption, i4.ɵNgSelectMultipleOption, i4.DefaultValueAccessor, i4.CheckboxControlValueAccessor, i4.SelectControlValueAccessor, i4.RadioControlValueAccessor, i4.NgControlStatus, i4.NgModel, i5.MJProgressBarComponent, i6.LoadingComponent, i7.ListDetailGridComponent, i3.ListDeltaConfirmComponent, i3.ListStatsComponent, i3.TagChipsComponent, i5.MJButtonDirective, i5.MJDialogComponent, i5.MJDialogActionsComponent, i5.MJEmptyStateComponent, i8.DatePipe], styles: [".list-detail-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n}\n\n.list-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 16px;\n flex-shrink: 0;\n gap: 16px;\n}\n\n.list-header__titleblock[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n\n.list-header[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.lineage-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n color: var(--mj-text-secondary);\n font-size: 12px;\n width: fit-content;\n}\n\n.lineage-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.lineage-badge__refreshed[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.refresh-mode-select[_ngcontent-%COMP%] {\n min-width: 100px;\n font-size: 13px;\n}\n\n.bulk-status-select[_ngcontent-%COMP%] {\n min-width: 130px;\n font-size: 13px;\n}\n\n\n\n\n\n.permission-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.permission-badge--viewer[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n.list-detail__tags[_ngcontent-%COMP%] {\n margin-top: 8px;\n}\n\n\n\n\n.grid-with-stats[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 280px;\n gap: 16px;\n flex: 1;\n min-height: 0;\n}\n\n.list-detail__stats[_ngcontent-%COMP%] {\n min-width: 0;\n overflow-y: auto;\n}\n\n@media (max-width: 900px) {\n .grid-with-stats[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .list-detail__stats[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n.custom-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-bottom: none;\n border-radius: 8px 8px 0 0;\n flex-shrink: 0;\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.selection-count[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n}\n\n.toolbar-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.remove-btn[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.grid-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 0 0 8px 8px;\n overflow: hidden;\n}\n\n\n\n.add-dropdown-wrapper[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.add-btn[_ngcontent-%COMP%] {\n font-size: 16px;\n padding: 8px 25px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.add-dropdown-arrow[_ngcontent-%COMP%] {\n font-size: 12px;\n margin-left: 4px;\n}\n\n.add-dropdown-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 240px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);\n z-index: 100;\n overflow: hidden;\n}\n\n.add-dropdown-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 10px 16px;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n\n.add-dropdown-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.add-dropdown-item-text[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.add-dropdown-item-desc[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n\n\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 8px 0;\n}\n\n.dialog-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n gap: 20px;\n}\n\n.dialog-message[_ngcontent-%COMP%] {\n text-align: center;\n padding: 20px;\n}\n\n.warning-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-status-warning);\n margin-bottom: 16px;\n display: block;\n}\n\n.dialog-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 8px 0;\n font-size: 15px;\n color: var(--mj-text-primary);\n}\n\n.dialog-note[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary) !important;\n font-size: 13px !important;\n}\n\n.progress-bar[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 300px;\n}\n\n\n\n\n\n\n.add-records-dialog[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.search-section[_ngcontent-%COMP%] {\n padding-bottom: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 12px;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] .search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 14px;\n pointer-events: none;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] .search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding-left: 32px;\n}\n\n.search-hint[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n.records-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.list-loading[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 40px;\n}\n\n.selection-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 8px;\n}\n\n.selection-info[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.records-scroll[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n max-height: 280px;\n}\n\n.record-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.record-item[_ngcontent-%COMP%]:hover:not(.in-list) {\n background: var(--mj-bg-surface-card);\n}\n\n.record-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.record-item.in-list[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n cursor: default;\n opacity: 0.7;\n}\n\n.record-checkbox[_ngcontent-%COMP%] {\n width: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.record-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.in-list-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n.record-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.in-list-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-radius: 10px;\n font-weight: 500;\n}\n\n\n\n\n\n\n.dialog-instruction[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.views-list[_ngcontent-%COMP%] {\n max-height: 320px;\n overflow-y: auto;\n}\n\n.view-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.view-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.view-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.view-item[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.view-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.view-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n\n\n.export-dialog[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 8px; }\n.export-section-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n margin-bottom: 8px;\n}\n.export-format-row[_ngcontent-%COMP%] { display: flex; gap: 8px; }\n.export-format-option[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 13px;\n background: var(--mj-bg-surface);\n}\n.export-format-option--selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n.export-format-option[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] { margin: 0; }\n.export-section-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 16px 0;\n}\n.export-fields-list[_ngcontent-%COMP%] {\n max-height: 280px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n.export-field-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 13px;\n cursor: pointer;\n}\n.export-field-row[_ngcontent-%COMP%]:last-child { border-bottom: none; }\n.export-field-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.export-field-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n align-items: center;\n font-size: 11.5px;\n}\n.export-field-actions[_ngcontent-%COMP%] a[_ngcontent-%COMP%] { color: var(--mj-text-link); }\n.export-field-actions[_ngcontent-%COMP%] .muted[_ngcontent-%COMP%] {\n margin-left: auto;\n color: var(--mj-text-muted);\n}"] });
2171
2162
  }
2172
2163
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SingleListDetailComponent, [{
2173
2164
  type: Component,
2174
- args: [{ standalone: false, selector: 'mj-list-detail', template: "<div class=\"list-detail-container\">\n <!-- Header with title and Add button -->\n <div class=\"list-header\">\n <div class=\"list-header__titleblock\">\n @if (listRecord) {\n <h1>{{ listRecord.Name }}</h1>\n } @else {\n <h1>List</h1>\n }\n @if (hasLineage) {\n <div class=\"lineage-badge\" [title]=\"'Source view: ' + (sourceViewName ?? 'unknown')\">\n <i class=\"fa-solid fa-link\"></i>\n <span>\n @if (listRecord?.UseSnapshot) {\n Snapshot of: <strong>{{ sourceViewName ?? '(unknown view)' }}</strong>\n } @else {\n Live view: <strong>{{ sourceViewName ?? '(unknown view)' }}</strong>\n }\n </span>\n @if (listRecord?.LastRefreshedAt) {\n <span class=\"lineage-badge__refreshed\">\n \u00B7 last refreshed {{ listRecord!.LastRefreshedAt | date:'medium' }}\n </span>\n }\n </div>\n }\n @if (listRecord) {\n <!-- Tags section (Phase 4.2). Editable on the detail view. -->\n <div class=\"list-detail__tags\">\n <mj-tag-chips\n [Provider]=\"Provider\"\n EntityName=\"MJ: Lists\"\n [RecordID]=\"listRecord.ID\"\n [Editable]=\"capabilities.CanEdit\"\n [MaxDisplay]=\"20\">\n </mj-tag-chips>\n </div>\n }\n </div>\n @if (capabilities.CanEdit) {\n <div class=\"add-dropdown-wrapper\">\n <button mjButton variant=\"primary\" class=\"add-btn\" (click)=\"toggleAddDropdown()\">\n <span class=\"fa-solid fa-plus\"></span>\n Add to List\n <span class=\"fa-solid fa-chevron-down add-dropdown-arrow\"></span>\n </button>\n @if (showAddDropdown) {\n <div class=\"add-dropdown-panel\">\n @for (option of addOptions; track option.Text) {\n <div class=\"add-dropdown-item\" (click)=\"onDropdownItemClick(option)\">\n <span class=\"add-dropdown-item-text\">{{ option.Text }}</span>\n @if (option.Description) {\n <span class=\"add-dropdown-item-desc\">{{ option.Description }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else if (currentLevel) {\n <!-- Viewer-perspective badge so users understand why mutation\n controls are absent. Mirrors mockup 19. -->\n <span class=\"permission-badge permission-badge--viewer\">\n <i class=\"fa-solid fa-eye\"></i>\n Viewer access\n </span>\n }\n </div>\n\n <!-- Custom Toolbar -->\n @if (!showLoader && listRecord) {\n <div class=\"custom-toolbar\">\n <div class=\"toolbar-left\">\n <span class=\"row-count\">{{ rowCount }} row{{ rowCount !== 1 ? 's' : '' }}</span>\n @if (selectedKeys.length > 0) {\n <span class=\"selection-count\">({{ selectedKeys.length }} selected)</span>\n }\n </div>\n <div class=\"toolbar-right\">\n @if (selectedKeys.length > 0 && capabilities.CanEdit) {\n <!-- Bulk-edit toolbar (Phase 5.2, mockups 23/24).\n Move/Copy open the target-list picker. Move then routes\n through the delta-confirm dialog because the source side\n drops; Copy is additive and applies directly. -->\n <button mjButton\n (click)=\"openMoveDialog()\"\n variant=\"flat\"\n class=\"toolbar-button\"\n title=\"Move selected records to another list\">\n <span class=\"fa-solid fa-arrow-right-arrow-left\"></span>\n Move\u2026\n </button>\n <button mjButton\n (click)=\"openCopyDialog()\"\n variant=\"flat\"\n class=\"toolbar-button\"\n title=\"Copy selected records to another list (keeps them here too)\">\n <span class=\"fa-solid fa-copy\"></span>\n Copy\u2026\n </button>\n <select\n class=\"mj-input mj-select bulk-status-select\"\n [(ngModel)]=\"bulkStatus\"\n [disabled]=\"isApplyingBulkStatus\"\n title=\"Set status on selected items\">\n <option value=\"\">Set status\u2026</option>\n <option value=\"Active\">Active</option>\n <option value=\"Complete\">Complete</option>\n <option value=\"Pending\">Pending</option>\n <option value=\"Disabled\">Disabled</option>\n <option value=\"Rejected\">Rejected</option>\n </select>\n <button mjButton\n (click)=\"applyBulkStatus()\"\n [disabled]=\"!bulkStatus || isApplyingBulkStatus\"\n variant=\"flat\"\n class=\"toolbar-button\">\n @if (isApplyingBulkStatus) {\n <span class=\"fa-solid fa-spinner fa-spin\"></span>\n Applying\u2026\n } @else {\n <span class=\"fa-solid fa-pen-to-square\"></span>\n Apply Status\n }\n </button>\n <button mjButton\n (click)=\"openRemoveDialog()\"\n variant=\"flat\"\n class=\"toolbar-button remove-btn\">\n <span class=\"fa-solid fa-trash\"></span>\n Remove from List\n </button>\n }\n @if (hasLineage && capabilities.CanRefresh) {\n <select\n class=\"mj-input mj-select refresh-mode-select\"\n [ngModel]=\"refreshMode\"\n (ngModelChange)=\"onRefreshModeChange($event)\"\n [disabled]=\"isPreviewingRefresh || isApplyingRefresh\"\n title=\"Refresh mode\">\n <option value=\"Additive\">Additive</option>\n <option value=\"Sync\">Sync</option>\n </select>\n <button mjButton\n (click)=\"onRefreshFromSource()\"\n [disabled]=\"isPreviewingRefresh || isApplyingRefresh\"\n variant=\"flat\"\n class=\"toolbar-button\">\n @if (isPreviewingRefresh) {\n <span class=\"fa-solid fa-spinner fa-spin\"></span>\n Previewing...\n } @else {\n <span class=\"fa-solid fa-cloud-arrow-down\"></span>\n Refresh from Source\n }\n </button>\n }\n <button mjButton\n (click)=\"onRefreshClick()\"\n variant=\"flat\"\n class=\"toolbar-button\">\n <span class=\"fa-solid fa-rotate\"></span>\n Refresh\n </button>\n <button mjButton\n (click)=\"onExportClick()\"\n variant=\"flat\"\n class=\"toolbar-button\">\n <span class=\"fa-solid fa-file-export\"></span>\n Export\n </button>\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (showLoader) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading list...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Grid + side stats panel (Phase 5.4). -->\n @if (!showLoader && listRecord) {\n <div class=\"grid-with-stats\">\n <div class=\"grid-container\">\n <mj-list-detail-grid\n #listDetailGrid\n [listId]=\"ListID\"\n [listEntity]=\"listRecord\"\n [autoNavigate]=\"true\"\n [height]=\"'auto'\"\n [showToolbar]=\"false\"\n [toolbarConfig]=\"gridToolbarConfig\"\n [selectionMode]=\"'checkbox'\"\n (rowClicked)=\"onRowClicked($event)\"\n (rowDoubleClicked)=\"onRowDoubleClicked($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n (dataLoaded)=\"onDataLoaded($event)\">\n </mj-list-detail-grid>\n </div>\n <aside class=\"list-detail__stats\">\n <mj-list-stats [Provider]=\"Provider\" [ListID]=\"listRecord.ID\" [RefreshTrigger]=\"statsRefreshTrigger\"></mj-list-stats>\n </aside>\n </div>\n }\n\n <!-- Refresh-from-source delta-confirm dialog -->\n <mj-list-delta-confirm\n [Visible]=\"refreshConfirmVisible && !!refreshDelta\"\n [Delta]=\"refreshDelta\"\n [TargetListName]=\"listRecord?.Name ?? null\"\n [SourceLabel]=\"sourceViewName\"\n (Confirm)=\"onRefreshConfirmCommit($event)\"\n (Cancel)=\"onRefreshConfirmCancel()\">\n </mj-list-delta-confirm>\n\n <!-- Move delta-confirm dialog (mockup 24). Shown only for Move,\n never for Copy. Drops on the source side require the user to\n acknowledge before Confirm enables. -->\n <mj-list-delta-confirm\n [Visible]=\"moveDeltaConfirmVisible && !!moveDelta\"\n [Delta]=\"moveDelta\"\n [TargetListName]=\"listRecord?.Name ?? null\"\n [SourceLabel]=\"'Move to ' + (moveCopySelectedTarget?.Name ?? 'target list')\"\n (Confirm)=\"onMoveConfirmCommit($event)\"\n (Cancel)=\"onMoveConfirmCancel()\">\n </mj-list-delta-confirm>\n</div>\n\n<!-- Move/Copy target picker (mockup 23). Lists every list owned by /\n shared with the current user that targets the same entity. -->\n@if (showMoveCopyDialog) {\n <mj-dialog\n [Visible]=\"true\"\n [Title]=\"(moveCopyMode === 'move' ? 'Move ' : 'Copy ') + selectedKeys.length + ' record' + (selectedKeys.length === 1 ? '' : 's') + ' to\u2026'\"\n (Close)=\"closeMoveCopyDialog()\"\n [MinWidth]=\"480\"\n [Width]=\"640\"\n [Height]=\"560\">\n <div class=\"dialog-content move-copy-dialog\">\n @if (isApplyingMoveCopy) {\n <div class=\"dialog-loading\">\n <mj-loading [text]=\"(moveCopyMode === 'move' ? 'Moving' : 'Copying') + ' records...'\" size=\"small\"></mj-loading>\n @if (moveCopyTotal > 0) {\n <mj-progress-bar\n [Value]=\"moveCopyProgressPercent\"\n class=\"progress-bar\">\n </mj-progress-bar>\n }\n </div>\n } @else {\n <p class=\"dialog-instruction\">\n Choose the target list. Both lists must hold the same entity ({{ listRecord?.Entity ?? 'records' }}).\n </p>\n <div class=\"search-section\">\n <div class=\"search-input-wrapper\">\n <span class=\"fa-solid fa-search search-icon\"></span>\n <input\n class=\"mj-input search-input\"\n type=\"text\"\n placeholder=\"Filter lists by name\u2026\"\n [(ngModel)]=\"moveCopyTargetSearch\" />\n </div>\n </div>\n @if (moveCopyTargetCandidatesLoading) {\n <div class=\"list-loading\">\n <mj-loading text=\"Loading lists...\" size=\"small\"></mj-loading>\n </div>\n } @else if (filteredMoveCopyTargets.length === 0) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-list empty-icon\"></span>\n <p>No other lists found for this entity.</p>\n <p class=\"dialog-note\">Create a new list first if you need a new target.</p>\n </div>\n } @else {\n <div class=\"records-scroll move-copy-targets\">\n @for (target of filteredMoveCopyTargets; track target.ID) {\n <div class=\"record-item\"\n [class.selected]=\"moveCopySelectedTarget?.ID === target.ID\"\n (click)=\"selectMoveCopyTarget(target)\">\n <div class=\"record-checkbox\">\n <input type=\"radio\"\n name=\"moveCopyTarget\"\n [checked]=\"moveCopySelectedTarget?.ID === target.ID\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"selectMoveCopyTarget(target)\">\n </div>\n <div class=\"record-name\">\n <strong>{{ target.Name }}</strong>\n @if (target.Description) {\n <span class=\"target-desc\"> \u2014 {{ target.Description }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n <mj-dialog-actions>\n <button mjButton\n (click)=\"confirmMoveCopy()\"\n [disabled]=\"!moveCopySelectedTarget || isApplyingMoveCopy\"\n variant=\"primary\">\n @if (moveCopyMode === 'move') {\n <span class=\"fa-solid fa-arrow-right-arrow-left\"></span>\n Continue\n } @else {\n <span class=\"fa-solid fa-copy\"></span>\n Copy {{ selectedKeys.length }}\n }\n </button>\n <button mjButton\n (click)=\"closeMoveCopyDialog()\"\n [disabled]=\"isApplyingMoveCopy\"\n variant=\"outline\">\n Cancel\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Remove from List Confirmation Dialog -->\n@if (showRemoveDialog) {\n <mj-dialog\n [Visible]=\"true\"\n Title=\"Remove from List\"\n (Close)=\"closeRemoveDialog()\"\n [MinWidth]=\"350\"\n [Width]=\"450\">\n <div class=\"dialog-content\">\n @if (isRemoving) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Removing records...\" size=\"small\"></mj-loading>\n @if (removeTotal > 0) {\n <mj-progress-bar\n [Value]=\"removeProgressPercent\"\n class=\"progress-bar\">\n </mj-progress-bar>\n }\n </div>\n } @else {\n <div class=\"dialog-message\">\n <span class=\"fa-solid fa-triangle-exclamation warning-icon\"></span>\n <p>Are you sure you want to remove <strong>{{ selectedKeys.length }}</strong> record{{ selectedKeys.length !== 1 ? 's' : '' }} from this list?</p>\n <p class=\"dialog-note\">This will not delete the records, only remove them from this list.</p>\n </div>\n }\n </div>\n <mj-dialog-actions>\n <button mjButton\n (click)=\"confirmRemoveFromList()\"\n [disabled]=\"isRemoving\"\n variant=\"danger\">\n Remove\n </button>\n <button mjButton\n (click)=\"closeRemoveDialog()\"\n [disabled]=\"isRemoving\"\n variant=\"outline\">\n Cancel\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Add Records Dialog -->\n@if (showAddRecordsDialog) {\n <mj-dialog\n [Visible]=\"true\"\n [Title]=\"'Add ' + (listRecord?.Entity || 'Records') + ' to List'\"\n (Close)=\"closeAddRecordsDialog()\"\n [MinWidth]=\"500\"\n [Width]=\"700\"\n [Height]=\"650\">\n <div class=\"dialog-content add-records-dialog\">\n @if (addDialogSaving) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Adding records to list...\" size=\"small\"></mj-loading>\n @if (addTotal > 0) {\n <mj-progress-bar\n [Value]=\"addProgressPercent\"\n class=\"progress-bar\">\n </mj-progress-bar>\n }\n </div>\n } @else {\n <!-- Search Input -->\n <div class=\"search-section\">\n <div class=\"search-input-wrapper\">\n <span class=\"fa-solid fa-search search-icon\"></span>\n <input\n class=\"mj-input search-input\"\n type=\"text\"\n [placeholder]=\"'Search ' + (listRecord?.Entity || 'records') + '...'\"\n [value]=\"addRecordsSearchFilter\"\n (input)=\"onAddRecordsSearchInputEvent($event)\" />\n </div>\n <span class=\"search-hint\">Type at least 2 characters to search</span>\n </div>\n <!-- Records List -->\n <div class=\"records-list\">\n @if (addDialogLoading) {\n <div class=\"list-loading\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n </div>\n } @else if (addableRecords.length === 0 && addRecordsSearchFilter.length >= 2) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-search empty-icon\"></span>\n <p>No records found matching \"{{ addRecordsSearchFilter }}\"</p>\n </div>\n } @else if (addableRecords.length === 0) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-list empty-icon\"></span>\n <p>Search for records to add to this list</p>\n </div>\n } @else {\n <!-- Selection controls -->\n <div class=\"selection-controls\">\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"selectAllAddable()\">Select All</button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"deselectAllAddable()\">Deselect All</button>\n <span class=\"selection-info\">{{ selectedAddableRecords.length }} selected</span>\n </div>\n <!-- Records -->\n <div class=\"records-scroll\">\n @for (record of addableRecords; track record.ID) {\n <div class=\"record-item\"\n [class.in-list]=\"record.isInList\"\n [class.selected]=\"record.isSelected\"\n (click)=\"toggleRecordSelection(record)\">\n <div class=\"record-checkbox\">\n @if (record.isInList) {\n <span class=\"fa-solid fa-check in-list-icon\" title=\"Already in list\"></span>\n } @else {\n <input type=\"checkbox\"\n [checked]=\"record.isSelected\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRecordSelection(record)\">\n }\n </div>\n <div class=\"record-name\">{{ record.Name }}</div>\n @if (record.isInList) {\n <span class=\"in-list-badge\">In List</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n <mj-dialog-actions>\n <button mjButton\n (click)=\"confirmAddRecords()\"\n [disabled]=\"addDialogSaving || selectedAddableRecords.length === 0\"\n variant=\"primary\">\n Add {{ selectedAddableRecords.length > 0 ? selectedAddableRecords.length : '' }} Record{{ selectedAddableRecords.length !== 1 ? 's' : '' }}\n </button>\n <button mjButton\n (click)=\"closeAddRecordsDialog()\"\n [disabled]=\"addDialogSaving\"\n variant=\"outline\">\n Cancel\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Export Dialog (mockup 26) \u2014 format + column picker -->\n@if (showExportDialog && listRecord) {\n <mj-dialog\n [Visible]=\"true\"\n [Title]=\"'Export ' + exportRecordCount + ' Record' + (exportRecordCount === 1 ? '' : 's')\"\n (Close)=\"closeExportDialog()\"\n [MinWidth]=\"520\"\n [Width]=\"640\"\n [Height]=\"640\">\n <div class=\"dialog-content export-dialog\">\n <label class=\"export-section-label\">Format</label>\n <div class=\"export-format-row\">\n <label class=\"export-format-option\"\n [class.export-format-option--selected]=\"exportFormat === 'excel'\"\n (click)=\"exportFormat = 'excel'\">\n <input type=\"radio\" name=\"exportFormat\" value=\"excel\" [(ngModel)]=\"exportFormat\">\n <i class=\"fa-solid fa-file-excel\" style=\"color: var(--mj-status-success);\"></i>\n <span>Excel (.xlsx)</span>\n </label>\n <label class=\"export-format-option\"\n [class.export-format-option--selected]=\"exportFormat === 'csv'\"\n (click)=\"exportFormat = 'csv'\">\n <input type=\"radio\" name=\"exportFormat\" value=\"csv\" [(ngModel)]=\"exportFormat\">\n <i class=\"fa-solid fa-file-csv\" style=\"color: var(--mj-text-secondary);\"></i>\n <span>CSV</span>\n </label>\n <label class=\"export-format-option\"\n [class.export-format-option--selected]=\"exportFormat === 'json'\"\n (click)=\"exportFormat = 'json'\">\n <input type=\"radio\" name=\"exportFormat\" value=\"json\" [(ngModel)]=\"exportFormat\">\n <i class=\"fa-solid fa-file-code\" style=\"color: var(--mj-brand-primary);\"></i>\n <span>JSON</span>\n </label>\n </div>\n\n <div class=\"export-section-divider\"></div>\n\n <label class=\"export-section-label\">Columns to include</label>\n <div class=\"export-fields-list\">\n @for (f of exportFields; track f.Name) {\n <label class=\"export-field-row\">\n <input type=\"checkbox\" [(ngModel)]=\"f.Selected\">\n <span>{{ f.DisplayName }}</span>\n </label>\n }\n </div>\n <div class=\"export-field-actions\">\n <a href=\"#\" (click)=\"selectAllExportFields(); $event.preventDefault()\">Select All</a>\n <a href=\"#\" (click)=\"selectNoneExportFields(); $event.preventDefault()\">Select None</a>\n <span class=\"muted\">{{ selectedExportFieldCount }} of {{ exportFields.length }} selected</span>\n </div>\n </div>\n <mj-dialog-actions>\n <button mjButton variant=\"primary\"\n [disabled]=\"selectedExportFieldCount === 0 || isExporting\"\n (click)=\"executeExport()\">\n @if (isExporting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Exporting\u2026\n } @else {\n <i class=\"fa-solid fa-download\"></i>\n Export {{ exportRecordCount }} Record{{ exportRecordCount === 1 ? '' : 's' }}\n }\n </button>\n <button mjButton variant=\"outline\" [disabled]=\"isExporting\" (click)=\"closeExportDialog()\">Cancel</button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Add From View Dialog -->\n@if (showAddFromViewDialog) {\n <mj-dialog\n [Visible]=\"true\"\n Title=\"Add Records from Views\"\n (Close)=\"closeAddFromViewDialog()\"\n [MinWidth]=\"400\"\n [Width]=\"600\"\n [Height]=\"500\">\n <div class=\"dialog-content\">\n @if (showAddFromViewLoader && fetchingRecordsToSave) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Loading records from views...\" size=\"small\"></mj-loading>\n </div>\n } @else if (showAddFromViewLoader && addFromViewTotal > 0) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Adding records to list...\" size=\"small\"></mj-loading>\n <mj-progress-bar\n [Value]=\"addFromViewProgressPercent\"\n class=\"progress-bar\">\n </mj-progress-bar>\n </div>\n } @else if (showAddFromViewLoader) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Loading views...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <p class=\"dialog-instruction\">Select views to add their records to this list:</p>\n <div class=\"views-list\">\n @if (!userViews || userViews.length === 0) {\n <div class=\"empty-results\">\n <span class=\"fa-solid fa-folder-open empty-icon\"></span>\n <p>No saved views found for this entity</p>\n </div>\n } @else {\n @for (view of userViews; track view.ID) {\n <div class=\"view-item\"\n [class.selected]=\"isViewSelected(view)\"\n (click)=\"toggleViewSelection(view)\">\n <input type=\"checkbox\"\n [checked]=\"isViewSelected(view)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleViewSelection(view)\">\n <span class=\"fa-solid fa-table-list view-icon\"></span>\n <span class=\"view-name\">{{ view.Name }}</span>\n </div>\n }\n }\n </div>\n }\n </div>\n <mj-dialog-actions>\n <button mjButton\n (click)=\"confirmAddFromView()\"\n [disabled]=\"showAddFromViewLoader || userViewsToAdd.length === 0\"\n variant=\"primary\">\n Add from {{ userViewsToAdd.length }} View{{ userViewsToAdd.length !== 1 ? 's' : '' }}\n </button>\n <button mjButton\n (click)=\"closeAddFromViewDialog()\"\n [disabled]=\"showAddFromViewLoader\"\n variant=\"outline\">\n Cancel\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n", styles: [".list-detail-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n}\n\n.list-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 16px;\n flex-shrink: 0;\n gap: 16px;\n}\n\n.list-header__titleblock {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n\n.list-header h1 {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.lineage-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n color: var(--mj-text-secondary);\n font-size: 12px;\n width: fit-content;\n}\n\n.lineage-badge i {\n color: var(--mj-brand-primary);\n}\n\n.lineage-badge__refreshed {\n color: var(--mj-text-muted);\n}\n\n.refresh-mode-select {\n min-width: 100px;\n font-size: 13px;\n}\n\n.bulk-status-select {\n min-width: 130px;\n font-size: 13px;\n}\n\n/* Viewer-perspective badge (mockup 19) \u2014 surfaced in the header when the\n user has read-only access so the missing mutation controls don't feel\n broken. */\n.permission-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.permission-badge--viewer {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Tags section on the list detail header (Phase 4.2). */\n.list-detail__tags {\n margin-top: 8px;\n}\n\n/* Grid + side stats two-column layout (Phase 5.4). Stats hides on\n narrow screens so the grid keeps its breathing room. */\n.grid-with-stats {\n display: grid;\n grid-template-columns: 1fr 280px;\n gap: 16px;\n flex: 1;\n min-height: 0;\n}\n\n.list-detail__stats {\n min-width: 0;\n overflow-y: auto;\n}\n\n@media (max-width: 900px) {\n .grid-with-stats {\n grid-template-columns: 1fr;\n }\n .list-detail__stats {\n display: none;\n }\n}\n\n/* Custom Toolbar */\n.custom-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-bottom: none;\n border-radius: 8px 8px 0 0;\n flex-shrink: 0;\n}\n\n.toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.selection-count {\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n}\n\n.toolbar-button span {\n font-size: 14px;\n}\n\n.remove-btn {\n color: var(--mj-status-error);\n}\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.grid-container {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 0 0 8px 8px;\n overflow: hidden;\n}\n\n/* Add Dropdown Button */\n.add-dropdown-wrapper {\n position: relative;\n}\n\n.add-btn {\n font-size: 16px;\n padding: 8px 25px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.add-dropdown-arrow {\n font-size: 12px;\n margin-left: 4px;\n}\n\n.add-dropdown-panel {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 240px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);\n z-index: 100;\n overflow: hidden;\n}\n\n.add-dropdown-item {\n display: flex;\n flex-direction: column;\n padding: 10px 16px;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n\n.add-dropdown-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.add-dropdown-item-text {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.add-dropdown-item-desc {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n/* ==========================================\n Dialog Styles\n ========================================== */\n\n.dialog-content {\n padding: 8px 0;\n}\n\n.dialog-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n gap: 20px;\n}\n\n.dialog-message {\n text-align: center;\n padding: 20px;\n}\n\n.warning-icon {\n font-size: 48px;\n color: var(--mj-status-warning);\n margin-bottom: 16px;\n display: block;\n}\n\n.dialog-message p {\n margin: 8px 0;\n font-size: 15px;\n color: var(--mj-text-primary);\n}\n\n.dialog-note {\n color: var(--mj-text-secondary) !important;\n font-size: 13px !important;\n}\n\n.progress-bar {\n width: 100%;\n max-width: 300px;\n}\n\n/* ==========================================\n Add Records Dialog\n ========================================== */\n\n.add-records-dialog {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.search-section {\n padding-bottom: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 12px;\n}\n\n.search-input-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-input-wrapper .search-icon {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 14px;\n pointer-events: none;\n}\n\n.search-input-wrapper .search-input {\n width: 100%;\n padding-left: 32px;\n}\n\n.search-hint {\n display: block;\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n.records-list {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.list-loading {\n display: flex;\n justify-content: center;\n padding: 40px;\n}\n\n.empty-results {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon {\n font-size: 32px;\n margin-bottom: 12px;\n color: var(--mj-border-strong);\n}\n\n.empty-results p {\n margin: 0;\n font-size: 14px;\n}\n\n.selection-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 8px;\n}\n\n.selection-info {\n margin-left: auto;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.records-scroll {\n flex: 1;\n overflow-y: auto;\n max-height: 280px;\n}\n\n.record-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.record-item:hover:not(.in-list) {\n background: var(--mj-bg-surface-card);\n}\n\n.record-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.record-item.in-list {\n background: var(--mj-bg-surface-card);\n cursor: default;\n opacity: 0.7;\n}\n\n.record-checkbox {\n width: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.record-checkbox input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.in-list-icon {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n.record-name {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.in-list-badge {\n font-size: 11px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-radius: 10px;\n font-weight: 500;\n}\n\n/* ==========================================\n Add From View Dialog\n ========================================== */\n\n.dialog-instruction {\n margin: 0 0 16px 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.views-list {\n max-height: 320px;\n overflow-y: auto;\n}\n\n.view-item {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.view-item:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.view-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.view-item input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.view-icon {\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.view-name {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n/* Export dialog (Phase 5.1, mockup 26) */\n.export-dialog { display: flex; flex-direction: column; gap: 8px; }\n.export-section-label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n margin-bottom: 8px;\n}\n.export-format-row { display: flex; gap: 8px; }\n.export-format-option {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 13px;\n background: var(--mj-bg-surface);\n}\n.export-format-option--selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n.export-format-option input[type=\"radio\"] { margin: 0; }\n.export-section-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 16px 0;\n}\n.export-fields-list {\n max-height: 280px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n.export-field-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 13px;\n cursor: pointer;\n}\n.export-field-row:last-child { border-bottom: none; }\n.export-field-row:hover { background: var(--mj-bg-surface-hover); }\n.export-field-actions {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n align-items: center;\n font-size: 11.5px;\n}\n.export-field-actions a { color: var(--mj-text-link); }\n.export-field-actions .muted {\n margin-left: auto;\n color: var(--mj-text-muted);\n}\n"] }]
2165
+ args: [{ standalone: false, selector: 'mj-list-detail', template: "<div class=\"list-detail-container\">\n <!-- Header with title and Add button -->\n <div class=\"list-header\">\n <div class=\"list-header__titleblock\">\n @if (listRecord) {\n <h1>{{ listRecord.Name }}</h1>\n } @else {\n <h1>List</h1>\n }\n @if (hasLineage) {\n <div class=\"lineage-badge\" [title]=\"'Source view: ' + (sourceViewName ?? 'unknown')\">\n <i class=\"fa-solid fa-link\"></i>\n <span>\n @if (listRecord?.UseSnapshot) {\n Snapshot of: <strong>{{ sourceViewName ?? '(unknown view)' }}</strong>\n } @else {\n Live view: <strong>{{ sourceViewName ?? '(unknown view)' }}</strong>\n }\n </span>\n @if (listRecord?.LastRefreshedAt) {\n <span class=\"lineage-badge__refreshed\">\n \u00B7 last refreshed {{ listRecord!.LastRefreshedAt | date:'medium' }}\n </span>\n }\n </div>\n }\n @if (listRecord) {\n <!-- Tags section (Phase 4.2). Editable on the detail view. -->\n <div class=\"list-detail__tags\">\n <mj-tag-chips\n [Provider]=\"Provider\"\n EntityName=\"MJ: Lists\"\n [RecordID]=\"listRecord.ID\"\n [Editable]=\"capabilities.CanEdit\"\n [MaxDisplay]=\"20\">\n </mj-tag-chips>\n </div>\n }\n </div>\n @if (capabilities.CanEdit) {\n <div class=\"add-dropdown-wrapper\">\n <button mjButton variant=\"primary\" class=\"add-btn\" (click)=\"toggleAddDropdown()\">\n <span class=\"fa-solid fa-plus\"></span>\n Add to List\n <span class=\"fa-solid fa-chevron-down add-dropdown-arrow\"></span>\n </button>\n @if (showAddDropdown) {\n <div class=\"add-dropdown-panel\">\n @for (option of addOptions; track option.Text) {\n <div class=\"add-dropdown-item\" (click)=\"onDropdownItemClick(option)\">\n <span class=\"add-dropdown-item-text\">{{ option.Text }}</span>\n @if (option.Description) {\n <span class=\"add-dropdown-item-desc\">{{ option.Description }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else if (currentLevel) {\n <!-- Viewer-perspective badge so users understand why mutation\n controls are absent. Mirrors mockup 19. -->\n <span class=\"permission-badge permission-badge--viewer\">\n <i class=\"fa-solid fa-eye\"></i>\n Viewer access\n </span>\n }\n </div>\n\n <!-- Custom Toolbar -->\n @if (!showLoader && listRecord) {\n <div class=\"custom-toolbar\">\n <div class=\"toolbar-left\">\n <span class=\"row-count\">{{ rowCount }} row{{ rowCount !== 1 ? 's' : '' }}</span>\n @if (selectedKeys.length > 0) {\n <span class=\"selection-count\">({{ selectedKeys.length }} selected)</span>\n }\n </div>\n <div class=\"toolbar-right\">\n @if (selectedKeys.length > 0 && capabilities.CanEdit) {\n <!-- Bulk-edit toolbar (Phase 5.2, mockups 23/24).\n Move/Copy open the target-list picker. Move then routes\n through the delta-confirm dialog because the source side\n drops; Copy is additive and applies directly. -->\n <button mjButton\n (click)=\"openMoveDialog()\"\n variant=\"flat\"\n class=\"toolbar-button\"\n title=\"Move selected records to another list\">\n <span class=\"fa-solid fa-arrow-right-arrow-left\"></span>\n Move\u2026\n </button>\n <button mjButton\n (click)=\"openCopyDialog()\"\n variant=\"flat\"\n class=\"toolbar-button\"\n title=\"Copy selected records to another list (keeps them here too)\">\n <span class=\"fa-solid fa-copy\"></span>\n Copy\u2026\n </button>\n <select\n class=\"mj-input mj-select bulk-status-select\"\n [(ngModel)]=\"bulkStatus\"\n [disabled]=\"isApplyingBulkStatus\"\n title=\"Set status on selected items\">\n <option value=\"\">Set status\u2026</option>\n <option value=\"Active\">Active</option>\n <option value=\"Complete\">Complete</option>\n <option value=\"Pending\">Pending</option>\n <option value=\"Disabled\">Disabled</option>\n <option value=\"Rejected\">Rejected</option>\n </select>\n <button mjButton\n (click)=\"applyBulkStatus()\"\n [disabled]=\"!bulkStatus || isApplyingBulkStatus\"\n variant=\"flat\"\n class=\"toolbar-button\">\n @if (isApplyingBulkStatus) {\n <span class=\"fa-solid fa-spinner fa-spin\"></span>\n Applying\u2026\n } @else {\n <span class=\"fa-solid fa-pen-to-square\"></span>\n Apply Status\n }\n </button>\n <button mjButton\n (click)=\"openRemoveDialog()\"\n variant=\"flat\"\n class=\"toolbar-button remove-btn\">\n <span class=\"fa-solid fa-trash\"></span>\n Remove from List\n </button>\n }\n @if (hasLineage && capabilities.CanRefresh) {\n <select\n class=\"mj-input mj-select refresh-mode-select\"\n [ngModel]=\"refreshMode\"\n (ngModelChange)=\"onRefreshModeChange($event)\"\n [disabled]=\"isPreviewingRefresh || isApplyingRefresh\"\n title=\"Refresh mode\">\n <option value=\"Additive\">Additive</option>\n <option value=\"Sync\">Sync</option>\n </select>\n <button mjButton\n (click)=\"onRefreshFromSource()\"\n [disabled]=\"isPreviewingRefresh || isApplyingRefresh\"\n variant=\"flat\"\n class=\"toolbar-button\">\n @if (isPreviewingRefresh) {\n <span class=\"fa-solid fa-spinner fa-spin\"></span>\n Previewing...\n } @else {\n <span class=\"fa-solid fa-cloud-arrow-down\"></span>\n Refresh from Source\n }\n </button>\n }\n <button mjButton\n (click)=\"onRefreshClick()\"\n variant=\"flat\"\n class=\"toolbar-button\">\n <span class=\"fa-solid fa-rotate\"></span>\n Refresh\n </button>\n <button mjButton\n (click)=\"onExportClick()\"\n variant=\"flat\"\n class=\"toolbar-button\">\n <span class=\"fa-solid fa-file-export\"></span>\n Export\n </button>\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (showLoader) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading list...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Grid + side stats panel (Phase 5.4). -->\n @if (!showLoader && listRecord) {\n <div class=\"grid-with-stats\">\n <div class=\"grid-container\">\n <mj-list-detail-grid\n #listDetailGrid\n [listId]=\"ListID\"\n [listEntity]=\"listRecord\"\n [autoNavigate]=\"true\"\n [height]=\"'auto'\"\n [showToolbar]=\"false\"\n [toolbarConfig]=\"gridToolbarConfig\"\n [selectionMode]=\"'checkbox'\"\n (rowClicked)=\"onRowClicked($event)\"\n (rowDoubleClicked)=\"onRowDoubleClicked($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n (dataLoaded)=\"onDataLoaded($event)\">\n </mj-list-detail-grid>\n </div>\n <aside class=\"list-detail__stats\">\n <mj-list-stats [Provider]=\"Provider\" [ListID]=\"listRecord.ID\" [RefreshTrigger]=\"statsRefreshTrigger\"></mj-list-stats>\n </aside>\n </div>\n }\n\n <!-- Refresh-from-source delta-confirm dialog -->\n <mj-list-delta-confirm\n [Visible]=\"refreshConfirmVisible && !!refreshDelta\"\n [Delta]=\"refreshDelta\"\n [TargetListName]=\"listRecord?.Name ?? null\"\n [SourceLabel]=\"sourceViewName\"\n (Confirm)=\"onRefreshConfirmCommit($event)\"\n (Cancel)=\"onRefreshConfirmCancel()\">\n </mj-list-delta-confirm>\n\n <!-- Move delta-confirm dialog (mockup 24). Shown only for Move,\n never for Copy. Drops on the source side require the user to\n acknowledge before Confirm enables. -->\n <mj-list-delta-confirm\n [Visible]=\"moveDeltaConfirmVisible && !!moveDelta\"\n [Delta]=\"moveDelta\"\n [TargetListName]=\"listRecord?.Name ?? null\"\n [SourceLabel]=\"'Move to ' + (moveCopySelectedTarget?.Name ?? 'target list')\"\n (Confirm)=\"onMoveConfirmCommit($event)\"\n (Cancel)=\"onMoveConfirmCancel()\">\n </mj-list-delta-confirm>\n</div>\n\n<!-- Move/Copy target picker (mockup 23). Lists every list owned by /\n shared with the current user that targets the same entity. -->\n@if (showMoveCopyDialog) {\n <mj-dialog\n [Visible]=\"true\"\n [Title]=\"(moveCopyMode === 'move' ? 'Move ' : 'Copy ') + selectedKeys.length + ' record' + (selectedKeys.length === 1 ? '' : 's') + ' to\u2026'\"\n (Close)=\"closeMoveCopyDialog()\"\n [MinWidth]=\"480\"\n [Width]=\"640\"\n [Height]=\"560\">\n <div class=\"dialog-content move-copy-dialog\">\n @if (isApplyingMoveCopy) {\n <div class=\"dialog-loading\">\n <mj-loading [text]=\"(moveCopyMode === 'move' ? 'Moving' : 'Copying') + ' records...'\" size=\"small\"></mj-loading>\n @if (moveCopyTotal > 0) {\n <mj-progress-bar\n [Value]=\"moveCopyProgressPercent\"\n class=\"progress-bar\">\n </mj-progress-bar>\n }\n </div>\n } @else {\n <p class=\"dialog-instruction\">\n Choose the target list. Both lists must hold the same entity ({{ listRecord?.Entity ?? 'records' }}).\n </p>\n <div class=\"search-section\">\n <div class=\"search-input-wrapper\">\n <span class=\"fa-solid fa-search search-icon\"></span>\n <input\n class=\"mj-input search-input\"\n type=\"text\"\n placeholder=\"Filter lists by name\u2026\"\n [(ngModel)]=\"moveCopyTargetSearch\" />\n </div>\n </div>\n @if (moveCopyTargetCandidatesLoading) {\n <div class=\"list-loading\">\n <mj-loading text=\"Loading lists...\" size=\"small\"></mj-loading>\n </div>\n } @else if (filteredMoveCopyTargets.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-list\"\n Title=\"No other lists found for this entity.\">\n <p class=\"dialog-note\">Create a new list first if you need a new target.</p>\n </mj-empty-state>\n } @else {\n <div class=\"records-scroll move-copy-targets\">\n @for (target of filteredMoveCopyTargets; track target.ID) {\n <div class=\"record-item\"\n [class.selected]=\"moveCopySelectedTarget?.ID === target.ID\"\n (click)=\"selectMoveCopyTarget(target)\">\n <div class=\"record-checkbox\">\n <input type=\"radio\"\n name=\"moveCopyTarget\"\n [checked]=\"moveCopySelectedTarget?.ID === target.ID\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"selectMoveCopyTarget(target)\">\n </div>\n <div class=\"record-name\">\n <strong>{{ target.Name }}</strong>\n @if (target.Description) {\n <span class=\"target-desc\"> \u2014 {{ target.Description }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n <mj-dialog-actions>\n <button mjButton\n (click)=\"confirmMoveCopy()\"\n [disabled]=\"!moveCopySelectedTarget || isApplyingMoveCopy\"\n variant=\"primary\">\n @if (moveCopyMode === 'move') {\n <span class=\"fa-solid fa-arrow-right-arrow-left\"></span>\n Continue\n } @else {\n <span class=\"fa-solid fa-copy\"></span>\n Copy {{ selectedKeys.length }}\n }\n </button>\n <button mjButton\n (click)=\"closeMoveCopyDialog()\"\n [disabled]=\"isApplyingMoveCopy\"\n variant=\"outline\">\n Cancel\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Remove from List Confirmation Dialog -->\n@if (showRemoveDialog) {\n <mj-dialog\n [Visible]=\"true\"\n Title=\"Remove from List\"\n (Close)=\"closeRemoveDialog()\"\n [MinWidth]=\"350\"\n [Width]=\"450\">\n <div class=\"dialog-content\">\n @if (isRemoving) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Removing records...\" size=\"small\"></mj-loading>\n @if (removeTotal > 0) {\n <mj-progress-bar\n [Value]=\"removeProgressPercent\"\n class=\"progress-bar\">\n </mj-progress-bar>\n }\n </div>\n } @else {\n <div class=\"dialog-message\">\n <span class=\"fa-solid fa-triangle-exclamation warning-icon\"></span>\n <p>Are you sure you want to remove <strong>{{ selectedKeys.length }}</strong> record{{ selectedKeys.length !== 1 ? 's' : '' }} from this list?</p>\n <p class=\"dialog-note\">This will not delete the records, only remove them from this list.</p>\n </div>\n }\n </div>\n <mj-dialog-actions>\n <button mjButton\n (click)=\"confirmRemoveFromList()\"\n [disabled]=\"isRemoving\"\n variant=\"danger\">\n Remove\n </button>\n <button mjButton\n (click)=\"closeRemoveDialog()\"\n [disabled]=\"isRemoving\"\n variant=\"outline\">\n Cancel\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Add Records Dialog -->\n@if (showAddRecordsDialog) {\n <mj-dialog\n [Visible]=\"true\"\n [Title]=\"'Add ' + (listRecord?.Entity || 'Records') + ' to List'\"\n (Close)=\"closeAddRecordsDialog()\"\n [MinWidth]=\"500\"\n [Width]=\"700\"\n [Height]=\"650\">\n <div class=\"dialog-content add-records-dialog\">\n @if (addDialogSaving) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Adding records to list...\" size=\"small\"></mj-loading>\n @if (addTotal > 0) {\n <mj-progress-bar\n [Value]=\"addProgressPercent\"\n class=\"progress-bar\">\n </mj-progress-bar>\n }\n </div>\n } @else {\n <!-- Search Input -->\n <div class=\"search-section\">\n <div class=\"search-input-wrapper\">\n <span class=\"fa-solid fa-search search-icon\"></span>\n <input\n class=\"mj-input search-input\"\n type=\"text\"\n [placeholder]=\"'Search ' + (listRecord?.Entity || 'records') + '...'\"\n [value]=\"addRecordsSearchFilter\"\n (input)=\"onAddRecordsSearchInputEvent($event)\" />\n </div>\n <span class=\"search-hint\">Type at least 2 characters to search</span>\n </div>\n <!-- Records List -->\n <div class=\"records-list\">\n @if (addDialogLoading) {\n <div class=\"list-loading\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n </div>\n } @else if (addableRecords.length === 0 && addRecordsSearchFilter.length >= 2) {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Icon=\"fa-solid fa-magnifying-glass\"\n [Title]=\"AddRecordsNoMatchTitle\" />\n } @else if (addableRecords.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-list\"\n Title=\"Search for records to add to this list\" />\n } @else {\n <!-- Selection controls -->\n <div class=\"selection-controls\">\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"selectAllAddable()\">Select All</button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"deselectAllAddable()\">Deselect All</button>\n <span class=\"selection-info\">{{ selectedAddableRecords.length }} selected</span>\n </div>\n <!-- Records -->\n <div class=\"records-scroll\">\n @for (record of addableRecords; track record.ID) {\n <div class=\"record-item\"\n [class.in-list]=\"record.isInList\"\n [class.selected]=\"record.isSelected\"\n (click)=\"toggleRecordSelection(record)\">\n <div class=\"record-checkbox\">\n @if (record.isInList) {\n <span class=\"fa-solid fa-check in-list-icon\" title=\"Already in list\"></span>\n } @else {\n <input type=\"checkbox\"\n [checked]=\"record.isSelected\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRecordSelection(record)\">\n }\n </div>\n <div class=\"record-name\">{{ record.Name }}</div>\n @if (record.isInList) {\n <span class=\"in-list-badge\">In List</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n <mj-dialog-actions>\n <button mjButton\n (click)=\"confirmAddRecords()\"\n [disabled]=\"addDialogSaving || selectedAddableRecords.length === 0\"\n variant=\"primary\">\n Add {{ selectedAddableRecords.length > 0 ? selectedAddableRecords.length : '' }} Record{{ selectedAddableRecords.length !== 1 ? 's' : '' }}\n </button>\n <button mjButton\n (click)=\"closeAddRecordsDialog()\"\n [disabled]=\"addDialogSaving\"\n variant=\"outline\">\n Cancel\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Export Dialog (mockup 26) \u2014 format + column picker -->\n@if (showExportDialog && listRecord) {\n <mj-dialog\n [Visible]=\"true\"\n [Title]=\"'Export ' + exportRecordCount + ' Record' + (exportRecordCount === 1 ? '' : 's')\"\n (Close)=\"closeExportDialog()\"\n [MinWidth]=\"520\"\n [Width]=\"640\"\n [Height]=\"640\">\n <div class=\"dialog-content export-dialog\">\n <label class=\"export-section-label\">Format</label>\n <div class=\"export-format-row\">\n <label class=\"export-format-option\"\n [class.export-format-option--selected]=\"exportFormat === 'excel'\"\n (click)=\"exportFormat = 'excel'\">\n <input type=\"radio\" name=\"exportFormat\" value=\"excel\" [(ngModel)]=\"exportFormat\">\n <i class=\"fa-solid fa-file-excel\" style=\"color: var(--mj-status-success);\"></i>\n <span>Excel (.xlsx)</span>\n </label>\n <label class=\"export-format-option\"\n [class.export-format-option--selected]=\"exportFormat === 'csv'\"\n (click)=\"exportFormat = 'csv'\">\n <input type=\"radio\" name=\"exportFormat\" value=\"csv\" [(ngModel)]=\"exportFormat\">\n <i class=\"fa-solid fa-file-csv\" style=\"color: var(--mj-text-secondary);\"></i>\n <span>CSV</span>\n </label>\n <label class=\"export-format-option\"\n [class.export-format-option--selected]=\"exportFormat === 'json'\"\n (click)=\"exportFormat = 'json'\">\n <input type=\"radio\" name=\"exportFormat\" value=\"json\" [(ngModel)]=\"exportFormat\">\n <i class=\"fa-solid fa-file-code\" style=\"color: var(--mj-brand-primary);\"></i>\n <span>JSON</span>\n </label>\n </div>\n\n <div class=\"export-section-divider\"></div>\n\n <label class=\"export-section-label\">Columns to include</label>\n <div class=\"export-fields-list\">\n @for (f of exportFields; track f.Name) {\n <label class=\"export-field-row\">\n <input type=\"checkbox\" [(ngModel)]=\"f.Selected\">\n <span>{{ f.DisplayName }}</span>\n </label>\n }\n </div>\n <div class=\"export-field-actions\">\n <a href=\"#\" (click)=\"selectAllExportFields(); $event.preventDefault()\">Select All</a>\n <a href=\"#\" (click)=\"selectNoneExportFields(); $event.preventDefault()\">Select None</a>\n <span class=\"muted\">{{ selectedExportFieldCount }} of {{ exportFields.length }} selected</span>\n </div>\n </div>\n <mj-dialog-actions>\n <button mjButton variant=\"primary\"\n [disabled]=\"selectedExportFieldCount === 0 || isExporting\"\n (click)=\"executeExport()\">\n @if (isExporting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Exporting\u2026\n } @else {\n <i class=\"fa-solid fa-download\"></i>\n Export {{ exportRecordCount }} Record{{ exportRecordCount === 1 ? '' : 's' }}\n }\n </button>\n <button mjButton variant=\"outline\" [disabled]=\"isExporting\" (click)=\"closeExportDialog()\">Cancel</button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Add From View Dialog -->\n@if (showAddFromViewDialog) {\n <mj-dialog\n [Visible]=\"true\"\n Title=\"Add Records from Views\"\n (Close)=\"closeAddFromViewDialog()\"\n [MinWidth]=\"400\"\n [Width]=\"600\"\n [Height]=\"500\">\n <div class=\"dialog-content\">\n @if (showAddFromViewLoader && fetchingRecordsToSave) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Loading records from views...\" size=\"small\"></mj-loading>\n </div>\n } @else if (showAddFromViewLoader && addFromViewTotal > 0) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Adding records to list...\" size=\"small\"></mj-loading>\n <mj-progress-bar\n [Value]=\"addFromViewProgressPercent\"\n class=\"progress-bar\">\n </mj-progress-bar>\n </div>\n } @else if (showAddFromViewLoader) {\n <div class=\"dialog-loading\">\n <mj-loading text=\"Loading views...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <p class=\"dialog-instruction\">Select views to add their records to this list:</p>\n <div class=\"views-list\">\n @if (!userViews || userViews.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-folder-open\"\n Title=\"No saved views found for this entity\" />\n } @else {\n @for (view of userViews; track view.ID) {\n <div class=\"view-item\"\n [class.selected]=\"isViewSelected(view)\"\n (click)=\"toggleViewSelection(view)\">\n <input type=\"checkbox\"\n [checked]=\"isViewSelected(view)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleViewSelection(view)\">\n <span class=\"fa-solid fa-table-list view-icon\"></span>\n <span class=\"view-name\">{{ view.Name }}</span>\n </div>\n }\n }\n </div>\n }\n </div>\n <mj-dialog-actions>\n <button mjButton\n (click)=\"confirmAddFromView()\"\n [disabled]=\"showAddFromViewLoader || userViewsToAdd.length === 0\"\n variant=\"primary\">\n Add from {{ userViewsToAdd.length }} View{{ userViewsToAdd.length !== 1 ? 's' : '' }}\n </button>\n <button mjButton\n (click)=\"closeAddFromViewDialog()\"\n [disabled]=\"showAddFromViewLoader\"\n variant=\"outline\">\n Cancel\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n", styles: [".list-detail-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n}\n\n.list-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 16px;\n flex-shrink: 0;\n gap: 16px;\n}\n\n.list-header__titleblock {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n\n.list-header h1 {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.lineage-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n color: var(--mj-text-secondary);\n font-size: 12px;\n width: fit-content;\n}\n\n.lineage-badge i {\n color: var(--mj-brand-primary);\n}\n\n.lineage-badge__refreshed {\n color: var(--mj-text-muted);\n}\n\n.refresh-mode-select {\n min-width: 100px;\n font-size: 13px;\n}\n\n.bulk-status-select {\n min-width: 130px;\n font-size: 13px;\n}\n\n/* Viewer-perspective badge (mockup 19) \u2014 surfaced in the header when the\n user has read-only access so the missing mutation controls don't feel\n broken. */\n.permission-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.permission-badge--viewer {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Tags section on the list detail header (Phase 4.2). */\n.list-detail__tags {\n margin-top: 8px;\n}\n\n/* Grid + side stats two-column layout (Phase 5.4). Stats hides on\n narrow screens so the grid keeps its breathing room. */\n.grid-with-stats {\n display: grid;\n grid-template-columns: 1fr 280px;\n gap: 16px;\n flex: 1;\n min-height: 0;\n}\n\n.list-detail__stats {\n min-width: 0;\n overflow-y: auto;\n}\n\n@media (max-width: 900px) {\n .grid-with-stats {\n grid-template-columns: 1fr;\n }\n .list-detail__stats {\n display: none;\n }\n}\n\n/* Custom Toolbar */\n.custom-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-bottom: none;\n border-radius: 8px 8px 0 0;\n flex-shrink: 0;\n}\n\n.toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.selection-count {\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n}\n\n.toolbar-button span {\n font-size: 14px;\n}\n\n.remove-btn {\n color: var(--mj-status-error);\n}\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.grid-container {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 0 0 8px 8px;\n overflow: hidden;\n}\n\n/* Add Dropdown Button */\n.add-dropdown-wrapper {\n position: relative;\n}\n\n.add-btn {\n font-size: 16px;\n padding: 8px 25px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.add-dropdown-arrow {\n font-size: 12px;\n margin-left: 4px;\n}\n\n.add-dropdown-panel {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 240px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);\n z-index: 100;\n overflow: hidden;\n}\n\n.add-dropdown-item {\n display: flex;\n flex-direction: column;\n padding: 10px 16px;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n\n.add-dropdown-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.add-dropdown-item-text {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.add-dropdown-item-desc {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n/* ==========================================\n Dialog Styles\n ========================================== */\n\n.dialog-content {\n padding: 8px 0;\n}\n\n.dialog-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n gap: 20px;\n}\n\n.dialog-message {\n text-align: center;\n padding: 20px;\n}\n\n.warning-icon {\n font-size: 48px;\n color: var(--mj-status-warning);\n margin-bottom: 16px;\n display: block;\n}\n\n.dialog-message p {\n margin: 8px 0;\n font-size: 15px;\n color: var(--mj-text-primary);\n}\n\n.dialog-note {\n color: var(--mj-text-secondary) !important;\n font-size: 13px !important;\n}\n\n.progress-bar {\n width: 100%;\n max-width: 300px;\n}\n\n/* ==========================================\n Add Records Dialog\n ========================================== */\n\n.add-records-dialog {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.search-section {\n padding-bottom: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 12px;\n}\n\n.search-input-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-input-wrapper .search-icon {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 14px;\n pointer-events: none;\n}\n\n.search-input-wrapper .search-input {\n width: 100%;\n padding-left: 32px;\n}\n\n.search-hint {\n display: block;\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n.records-list {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.list-loading {\n display: flex;\n justify-content: center;\n padding: 40px;\n}\n\n.selection-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 8px;\n}\n\n.selection-info {\n margin-left: auto;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.records-scroll {\n flex: 1;\n overflow-y: auto;\n max-height: 280px;\n}\n\n.record-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.record-item:hover:not(.in-list) {\n background: var(--mj-bg-surface-card);\n}\n\n.record-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.record-item.in-list {\n background: var(--mj-bg-surface-card);\n cursor: default;\n opacity: 0.7;\n}\n\n.record-checkbox {\n width: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.record-checkbox input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.in-list-icon {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n.record-name {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.in-list-badge {\n font-size: 11px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-radius: 10px;\n font-weight: 500;\n}\n\n/* ==========================================\n Add From View Dialog\n ========================================== */\n\n.dialog-instruction {\n margin: 0 0 16px 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.views-list {\n max-height: 320px;\n overflow-y: auto;\n}\n\n.view-item {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.15s;\n gap: 12px;\n}\n\n.view-item:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.view-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.view-item input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.view-icon {\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.view-name {\n flex: 1;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n/* Export dialog (Phase 5.1, mockup 26) */\n.export-dialog { display: flex; flex-direction: column; gap: 8px; }\n.export-section-label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n margin-bottom: 8px;\n}\n.export-format-row { display: flex; gap: 8px; }\n.export-format-option {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 13px;\n background: var(--mj-bg-surface);\n}\n.export-format-option--selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n.export-format-option input[type=\"radio\"] { margin: 0; }\n.export-section-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 16px 0;\n}\n.export-fields-list {\n max-height: 280px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n.export-field-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 13px;\n cursor: pointer;\n}\n.export-field-row:last-child { border-bottom: none; }\n.export-field-row:hover { background: var(--mj-bg-surface-hover); }\n.export-field-actions {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n align-items: center;\n font-size: 11.5px;\n}\n.export-field-actions a { color: var(--mj-text-link); }\n.export-field-actions .muted {\n margin-left: auto;\n color: var(--mj-text-muted);\n}\n"] }]
2175
2166
  }], () => [{ type: i1.SharedService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i2.ExportService }, { type: i3.ListSharingService }], { ListID: [{
2176
2167
  type: Input
2177
2168
  }], listDetailGrid: [{