@memberjunction/ng-entity-viewer 5.39.0 → 5.40.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 (79) hide show
  1. package/dist/__tests__/view-types.test.d.ts +2 -0
  2. package/dist/__tests__/view-types.test.d.ts.map +1 -0
  3. package/dist/__tests__/view-types.test.js +102 -0
  4. package/dist/__tests__/view-types.test.js.map +1 -0
  5. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
  6. package/dist/lib/entity-data-grid/entity-data-grid.component.js +8 -0
  7. package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
  8. package/dist/lib/entity-viewer/entity-viewer.component.d.ts +356 -341
  9. package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
  10. package/dist/lib/entity-viewer/entity-viewer.component.js +993 -1097
  11. package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
  12. package/dist/lib/view-config-panel/view-config-panel.component.d.ts +126 -126
  13. package/dist/lib/view-config-panel/view-config-panel.component.js +635 -635
  14. package/dist/lib/view-config-panel/view-config-panel.component.js.map +1 -1
  15. package/dist/lib/view-selector/view-selector.component.d.ts +226 -0
  16. package/dist/lib/view-selector/view-selector.component.d.ts.map +1 -0
  17. package/dist/lib/view-selector/view-selector.component.js +861 -0
  18. package/dist/lib/view-selector/view-selector.component.js.map +1 -0
  19. package/dist/lib/view-type-switcher/view-type-switcher.component.d.ts +114 -0
  20. package/dist/lib/view-type-switcher/view-type-switcher.component.d.ts.map +1 -0
  21. package/dist/lib/view-type-switcher/view-type-switcher.component.js +209 -0
  22. package/dist/lib/view-type-switcher/view-type-switcher.component.js.map +1 -0
  23. package/dist/lib/view-types/descriptors/cards-view-type.d.ts +18 -0
  24. package/dist/lib/view-types/descriptors/cards-view-type.d.ts.map +1 -0
  25. package/dist/lib/view-types/descriptors/cards-view-type.js +31 -0
  26. package/dist/lib/view-types/descriptors/cards-view-type.js.map +1 -0
  27. package/dist/lib/view-types/descriptors/grid-view-type.d.ts +17 -0
  28. package/dist/lib/view-types/descriptors/grid-view-type.d.ts.map +1 -0
  29. package/dist/lib/view-types/descriptors/grid-view-type.js +30 -0
  30. package/dist/lib/view-types/descriptors/grid-view-type.js.map +1 -0
  31. package/dist/lib/view-types/descriptors/map-view-type.d.ts +21 -0
  32. package/dist/lib/view-types/descriptors/map-view-type.d.ts.map +1 -0
  33. package/dist/lib/view-types/descriptors/map-view-type.js +35 -0
  34. package/dist/lib/view-types/descriptors/map-view-type.js.map +1 -0
  35. package/dist/lib/view-types/descriptors/timeline-view-type.d.ts +22 -0
  36. package/dist/lib/view-types/descriptors/timeline-view-type.d.ts.map +1 -0
  37. package/dist/lib/view-types/descriptors/timeline-view-type.js +40 -0
  38. package/dist/lib/view-types/descriptors/timeline-view-type.js.map +1 -0
  39. package/dist/lib/view-types/index.d.ts +20 -0
  40. package/dist/lib/view-types/index.d.ts.map +1 -0
  41. package/dist/lib/view-types/index.js +29 -0
  42. package/dist/lib/view-types/index.js.map +1 -0
  43. package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts +93 -0
  44. package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts.map +1 -0
  45. package/dist/lib/view-types/renderers/cards-view-renderer.component.js +144 -0
  46. package/dist/lib/view-types/renderers/cards-view-renderer.component.js.map +1 -0
  47. package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts +273 -0
  48. package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts.map +1 -0
  49. package/dist/lib/view-types/renderers/grid-view-renderer.component.js +558 -0
  50. package/dist/lib/view-types/renderers/grid-view-renderer.component.js.map +1 -0
  51. package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts +135 -0
  52. package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts.map +1 -0
  53. package/dist/lib/view-types/renderers/map-view-renderer.component.js +216 -0
  54. package/dist/lib/view-types/renderers/map-view-renderer.component.js.map +1 -0
  55. package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts +176 -0
  56. package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts.map +1 -0
  57. package/dist/lib/view-types/renderers/timeline-view-renderer.component.js +535 -0
  58. package/dist/lib/view-types/renderers/timeline-view-renderer.component.js.map +1 -0
  59. package/dist/lib/view-types/view-type.contracts.d.ts +235 -0
  60. package/dist/lib/view-types/view-type.contracts.d.ts.map +1 -0
  61. package/dist/lib/view-types/view-type.contracts.js +51 -0
  62. package/dist/lib/view-types/view-type.contracts.js.map +1 -0
  63. package/dist/lib/view-types/view-type.engine.d.ts +76 -0
  64. package/dist/lib/view-types/view-type.engine.d.ts.map +1 -0
  65. package/dist/lib/view-types/view-type.engine.js +138 -0
  66. package/dist/lib/view-types/view-type.engine.js.map +1 -0
  67. package/dist/lib/view-workspace/view-workspace.component.d.ts +451 -0
  68. package/dist/lib/view-workspace/view-workspace.component.d.ts.map +1 -0
  69. package/dist/lib/view-workspace/view-workspace.component.js +1212 -0
  70. package/dist/lib/view-workspace/view-workspace.component.js.map +1 -0
  71. package/dist/module.d.ts +20 -11
  72. package/dist/module.d.ts.map +1 -1
  73. package/dist/module.js +50 -8
  74. package/dist/module.js.map +1 -1
  75. package/dist/public-api.d.ts +8 -0
  76. package/dist/public-api.d.ts.map +1 -1
  77. package/dist/public-api.js +14 -0
  78. package/dist/public-api.js.map +1 -1
  79. package/package.json +16 -15
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-view-renderer.component.js","sourceRoot":"","sources":["../../../../src/lib/view-types/renderers/grid-view-renderer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAChI,OAAO,EAA6B,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAQrE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;;;;;;;;;IAyIrE,oDAMC;IADC,AADA,4NAAY,uCAAgC,KAAC,qMACnC,+BAAwB,KAAC;IAErC,iBAA4B;;;IAJ1B,AADA,AADA,0CAAqB,4CACe,uCACL;;AAtGvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AA4EH,MAAM,OAAO,yBAA0B,SAAQ,oBAAoB;IACjE,0FAA0F;IAClF,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAExC,wEAAwE;IAExE,qGAAqG;IAC5F,MAAM,GAAsB,IAAI,CAAC;IAE1C,gGAAgG;IACvF,OAAO,GAA8B,EAAE,CAAC;IAEjD,mEAAmE;IAC1D,gBAAgB,GAAkB,IAAI,CAAC;IAEhD,4EAA4E;IACnE,UAAU,GAAkB,IAAI,CAAC;IAE1C,oGAAoG;IAC3F,MAAM,GAAmB,EAAE,CAAC;IAErC,sDAAsD;IAEtD,6FAA6F;IACpF,gBAAgB,CAAU;IAEnC,kGAAkG;IACzF,IAAI,CAAU;IAEvB,+EAA+E;IACtE,QAAQ,CAAU;IAE3B,oGAAoG;IAC3F,SAAS,CAAW;IAE7B,uEAAuE;IAEvE,qGAAqG;IAC3F,cAAc,GAAG,IAAI,YAAY,EAAW,CAAC;IAEvD,qGAAqG;IAC3F,YAAY,GAAG,IAAI,YAAY,EAAW,CAAC;IAErD,oGAAoG;IAC1F,aAAa,GAAG,IAAI,YAAY,EAAkB,CAAC;IAE7D,uFAAuF;IAC7E,WAAW,GAAG,IAAI,YAAY,EAAmB,CAAC;IAE5D;;;OAGG;IACO,0BAA0B,GAAG,IAAI,YAAY,EAA+B,CAAC;IAEvF,yGAAyG;IAC/F,qBAAqB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE3D;;;OAGG;IAC0B,IAAI,CAA2B;IAE5D,mEAAmE;IACnE,2DAA2D;IAC3D,mEAAmE;IACnE,+EAA+E;IAE/E,qGAAqG;IAC3F,wBAAwB,GAAG,KAAK,CAAC;IAE3C,+FAA+F;IACrF,oBAAoB,GAAsC,IAAI,CAAC;IAEzE,4GAA4G;IAClG,iBAAiB,GAAG,KAAK,CAAC;IAEpC,oEAAoE;IAC5D,oBAAoB,GAA8B,EAAE,CAAC;IAE7D,6FAA6F;IACnF,oBAAoB,GAAG,uDAAuD,CAAC;IAEzF,mEAAmE;IACnE,wEAAwE;IACxE,mEAAmE;IAEnE,gFAAgF;IAChF,IAAI,oBAAoB;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;IACzC,CAAC;IAED,kFAAkF;IAClF,IAAI,sBAAsB;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,UAAU,CAAC;IACjD,CAAC;IAED,2FAA2F;IAC3F,IAAI,4BAA4B;QAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,IAAI,CAAC;IACjD,CAAC;IAED,8EAA8E;IAC9E,IAAI,kBAAkB;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC;IACvC,CAAC;IAED,yGAAyG;IACzG,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC;IACtD,CAAC;IAED;;;;OAIG;IACH,IAAI,eAAe;QACjB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAC5B,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mEAAmE;IACnE,mDAAmD;IACnD,mEAAmE;IAEnE;;;OAGG;IACH,eAAe,CAAC,KAA6B;QAC3C,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,4FAA4F;IAC5F,qBAAqB,CAAC,KAAmC;QACvD,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,KAAyB;QACnC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACjG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAEhC,MAAM,SAAS,GAAkB,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,CAAC;QACtE,SAAS,CAAC,YAAY,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACvG,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;QAC5C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,KAA4B;QAC7C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;QAC7D,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,iBAAiB,CAAC,aAAuB;QACvC,8FAA8F;IAChG,CAAC;IAED;;;;;OAKG;IACH,iBAAiB,CAAC,KAA2B;QAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,iBAAiB,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAChG,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,oGAAoG;IACpG,gBAAgB;QACd,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,KAAsB;QACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,mEAAmE;IACnE,0BAA0B;IAC1B,mEAAmE;IAEnE;;;;OAIG;IACH,oBAAoB;QAClB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,mEAAmE;IACnE,iGAAiG;IACjG,oGAAoG;IACpG,2CAA2C;IAC3C,mEAAmE;IAEnE,mEAAmE;IACnE,kEAAkE;IAClE,mEAAmE;IAEnE;;;;;OAKG;IACH,oBAAoB,CAAC,KAA0F;QAC7G,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC;QAC/C,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5D,OAAO;QACT,CAAC;QAED,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACpG,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAChE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QACzC,MAAM,WAAW,GAAG,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,WAAW,kBAAkB,CAAC;QAE7H,IAAI,CAAC,oBAAoB,GAAG;YAC1B,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,UAAU,EAAE,MAAM,CAAC,IAAI;YACvB,SAAS;YACT,kBAAkB;YAClB,WAAW,EAAE,IAAI;YACjB,WAAW,EAAE,WAAW,KAAK,CAAC;YAC9B,cAAc,EAAE,WAAW,KAAK,CAAC;YACjC,WAAW;SACZ,CAAC;QACF,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,uFAAuF;IACvF,wBAAwB,CAAC,OAA6B;QACpD,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC;QACtC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,0DAA0D;IAC1D,sBAAsB;QACpB,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC;QACtC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACK,oBAAoB,CAAC,MAA+B,EAAE,MAAkB;QAC9E,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAChD,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;gBACtB,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QACD,OAAO,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,SAAS,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACK,iBAAiB,CAAC,OAAkC,EAAE,MAAkB;QAC9E,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QAChD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,OAAO;aACX,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACd,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;YAClC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,mEAAmE;IACnE,0EAA0E;IAC1E,mEAAmE;IAEnE;;;OAGG;IACH,mBAAmB,CAAC,OAAkC;QACpD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO;QACT,CAAC;QACD,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC;QACpC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,oBAAoB,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC,CAAC,yCAAyC,KAAK,WAAW,CAAC;QACrJ,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,iBAAiB;QACrB,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC;QAC1C,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAE/B,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC;QACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC;QAElC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC9C,IAAI,CAAC;gBACH,+FAA+F;gBAC/F,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;gBACnE,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;gBACnC,IAAI,OAAO,EAAE,CAAC;oBACZ,UAAU,GAAG,IAAI,CAAC;gBACpB,CAAC;qBAAM,CAAC;oBACN,QAAQ,CAAC,kBAAkB,GAAG,CAAC,YAAY,EAAE,eAAe,IAAI,eAAe,EAAE,CAAC,CAAC;gBACrF,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,QAAQ,CAAC,qBAAqB,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACxH,CAAC;QACH,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,gFAAgF;YAChF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,kFAAkF;IAClF,iBAAiB;QACf,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,mEAAmE;IACnE,UAAU;IACV,mEAAmE;IAEnE,mGAAmG;IAC3F,sBAAsB;QAC5B,MAAM,GAAG,GAAoB,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACtB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;QACjD,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;YACf,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;QACpB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;OAGG;IACK,qBAAqB,CAAC,QAAgB;QAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;QAClF,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACnC,CAAC;iRA5ZU,yBAAyB,yBAAzB,yBAAyB;6DAAzB,yBAAyB;;;;;;;YAtElC,iDA4BC;YADC,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,+KAAiB,2BAAuB,KAAC,8KAClB,iCAA6B,KAAC,0JACxC,uBAAmB,KAAC,wKACb,8BAA0B,KAAC,sKAC5B,6BAAyB,KAAC,8JAC3B,sBAAkB,KAAC,sKACf,0BAAsB,KAAC,0KACxB,+BAA2B,KAAC,4KAC3B,gCAA4B,KAAC,sKAChC,6BAAyB,KAAC,4JAC/B,wBAAoB,KAAC;YAErC,iBAAsB;YAOtB,iHAA4B;YAY5B,+CAUC;YADC,AADA,kKAAa,uBAAmB,KAAC,qJACpB,uBAAmB,KAAC;YAEnC,iBAAuB;;YA3CrB,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,uCAAqB,qBACL,+BACU,oCACK,2CACO,kBACrB,oBACE,yCACiB,0EACQ,6CACJ,yDACY,qCACpB,mCACF,4CACS,kCACV;YAoB/B,eASC;YATD,mDASC;YAIC,cAA4B;YAE5B,AAFA,8CAA4B,qCAEI;;;iFAmBzB,yBAAyB;cA3ErC,SAAS;6BACI,KAAK,YACP,uBAAuB,iBAClB,iBAAiB,CAAC,IAAI,YAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DT;;kBAiBA,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAKL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAKL,MAAM;;kBAGN,MAAM;;kBAGN,MAAM;;kBAGN,MAAM;;kBAMN,MAAM;;kBAGN,MAAM;;kBAMN,SAAS;mBAAC,MAAM;;kFA9DN,yBAAyB;AA+ZtC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,0DAA0D;AAC5D,CAAC","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewEncapsulation, ViewChild, ChangeDetectorRef, inject } from '@angular/core';\nimport { EntityInfo, RunViewParams, LogError } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { ListManagementDialogConfig, ListManagementResult } from '@memberjunction/ng-list-management';\nimport { IViewRenderer, ViewDataRequest, ViewRelatedRecordNavigation } from '../view-type.contracts';\nimport { ViewGridState } from '../../types';\nimport { GridSelectionMode, GridToolbarConfig, ForeignKeyClickEvent } from '../../entity-data-grid/models/grid-types';\nimport { AfterRowClickEventArgs, AfterRowDoubleClickEventArgs, AfterSortEventArgs } from '../../entity-data-grid/events/grid-events';\nimport { GridStateChangedEvent } from '../../types';\nimport { buildPkString, buildCompositeKey } from '../../utils/record.util';\nimport { EntityDataGridComponent } from '../../entity-data-grid/entity-data-grid.component';\n\n/**\n * Opaque per-view configuration for the Grid view type.\n * -----------------------------------------------------\n * This is the blob the host persists verbatim against the active `ViewTypeID` and never\n * inspects (see {@link IViewRenderer.configChanged}). The renderer seeds the\n * `<mj-entity-data-grid>` bindings from these fields, applying sensible defaults when a\n * field is absent (see {@link GridViewRendererComponent}). It is intentionally a plain,\n * fully-serializable shape — every field is optional so an empty `{}` is a valid config.\n */\nexport interface GridViewConfig {\n /**\n * Persisted grid state (columns/widths/order/sort) from a User View. Mutated in place when\n * the grid emits sort or generic grid-state changes, then surfaced via `configChanged` so the\n * host persists it. Fed straight into `[GridState]`.\n */\n gridState?: ViewGridState;\n /** Whether the grid's own toolbar is shown. Defaults to `true` when absent. */\n showToolbar?: boolean;\n /** The grid toolbar configuration. Fed into `[ToolbarConfig]`. */\n toolbarConfig?: GridToolbarConfig;\n /** Row selection mode. Defaults to `'checkbox'` when absent. */\n selectionMode?: GridSelectionMode;\n /** Whether the \"Add to List\" button is shown. Defaults to `true` when absent. */\n showAddToListButton?: boolean;\n /** Whether the pager is shown. Defaults to `true` when absent. */\n showPager?: boolean;\n /** Page size for the grid's pager. Falls back to the `pageSize` input when absent. */\n pageSize?: number;\n /**\n * Explicit RunViewParams for the grid's data source. When absent the renderer builds a minimal\n * dynamic-view params object from {@link entity}. Fed into `[Params]`.\n */\n params?: RunViewParams;\n}\n\n/**\n * GridViewRendererComponent\n * -------------------------\n * The Grid **view type** renderer — a fully self-contained {@link IViewRenderer} adapter that hosts\n * the existing {@link EntityDataGridComponent} (`<mj-entity-data-grid>`) inside the entity-viewer's\n * pluggable view-type system. It is the dynamic-mounted plug-in that the `GridViewType` descriptor\n * points at.\n *\n * **Architectural intent — the container knows nothing about grids, and grid *features* never bubble\n * up.** The host (entity-viewer) binds only the generic {@link IViewRenderer} surface: the core\n * inputs (`entity` / `provider` / `records` / `selectedRecordId` / `filterText` / `config`), the\n * generic data-context inputs (`totalRecordCount` / `page` / `pageSize` / `isLoading`), and a small\n * set of generic outputs. There is **no opaque `hostAction` channel** — everything a grid does is\n * resolved through one of these three categories:\n *\n * 1. **Self-contained (owned end-to-end — never bubbles up):**\n * - **Export** → owned entirely by `<mj-entity-data-grid>` itself (its `onExportClick` opens its\n * OWN export dialog with format/sampling via `ExportService`). This wrapper does NOT host an\n * export dialog — doing so produced two stacked dialogs.\n * - **Add to List** → hosts `<mj-list-management-dialog>` ({@link ListManagementModule}). On\n * `(AddToListRequested)` the wrapper builds a {@link ListManagementDialogConfig} from the\n * entity + selected records and opens the dialog.\n * - **Delete** → hosts the Generic `<mj-ev-confirm-dialog>` (from {@link EntityViewerModule}).\n * On `(DeleteButtonClick)` the wrapper confirms, deletes via the MJ entity layer, then\n * re-requests data so the host reloads the current page.\n * - **Refresh** → on `(RefreshButtonClick)` the wrapper re-emits {@link dataRequest} so the host\n * reloads. No feature event leaves the wrapper.\n * - **Selection** → kept INTERNAL; it only drives the wrapper's own add-to-list. Never bubbles.\n *\n * 2. **Navigation (the ONLY legitimate upward signals — routing lives in the outer app):**\n * - Row double-click → {@link recordOpened}.\n * - Foreign-key cell click `(ForeignKeyClick)` → {@link openRelatedRecordRequested}.\n * - New button `(NewButtonClick)` → {@link createRecordRequested}.\n *\n * 3. **Container ↔ plug-in generic coordination (NOT outer-app signals):**\n * - Sort `(AfterSort)` → {@link dataRequest} (`sort`) + persisted into `config.gridState` via\n * {@link configChanged}.\n * - Pager `(PageChange)` → {@link dataRequest} (`page` / `pageSize`).\n * - Generic grid-state `(GridStateChanged)` → merged into `config.gridState` + {@link configChanged}.\n *\n * **Seeding the grid from `config` with defaults:** absent config fields fall back to sensible\n * defaults so a brand-new view (`config === {}`) renders a fully-functional grid — toolbar on,\n * checkbox selection, add-to-list on, pager on. The grid never loads its own data\n * (`[AllowLoad]=\"false\"`) — the host owns the fetch.\n *\n * This is an NgModule-declared (`standalone: false`) component, declared in `EntityViewerModule`.\n * It renders `<mj-entity-data-grid>` + the Generic `<mj-list-management-dialog>` / `<mj-ev-confirm-dialog>`\n * straight from the module's compilation scope (the module imports `ListManagementModule` and declares\n * the grid + confirm dialog; the grid component brings its own export dialog) — so there's\n * no `imports` array and, crucially, no self-import of `EntityViewerModule`: the module loads the\n * view-type descriptors, which reference these wrappers, so a wrapper importing the module back would\n * form a runtime import cycle (NG0919).\n *\n * Inputs use the camelCase names mandated by the {@link IViewRenderer} contract (the host binds them\n * by those exact names via `setInput`), rather than MJ's usual PascalCase for public members —\n * mirroring the Cards and Cluster renderers.\n */\n@Component({\n standalone: false,\n selector: 'mj-grid-view-renderer',\n encapsulation: ViewEncapsulation.None,\n template: `\n <mj-entity-data-grid\n #grid\n [Provider]=\"Provider\"\n [Data]=\"records\"\n [Params]=\"effectiveParams\"\n [FilterText]=\"filterText ?? ''\"\n [GridState]=\"config.gridState ?? null\"\n [Height]=\"'auto'\"\n [AllowLoad]=\"false\"\n [ShowToolbar]=\"effectiveShowToolbar\"\n [ToolbarConfig]=\"config.toolbarConfig ?? {}\"\n [SelectionMode]=\"effectiveSelectionMode\"\n [ShowAddToListButton]=\"effectiveShowAddToListButton\"\n [ShowPager]=\"effectiveShowPager\"\n [PageSize]=\"effectivePageSize\"\n [TotalRowCount]=\"totalRecordCount ?? 0\"\n [PagerPageNumber]=\"page ?? 1\"\n (AfterRowClick)=\"onAfterRowClick($event)\"\n (AfterRowDoubleClick)=\"onAfterRowDoubleClick($event)\"\n (AfterSort)=\"onAfterSort($event)\"\n (GridStateChanged)=\"onGridStateChanged($event)\"\n (SelectionChange)=\"onSelectionChange($event)\"\n (NewButtonClick)=\"onNewButtonClick()\"\n (RefreshButtonClick)=\"onRefreshButtonClick()\"\n (DeleteButtonClick)=\"onDeleteButtonClick($event)\"\n (AddToListRequested)=\"onAddToListRequested($event)\"\n (ForeignKeyClick)=\"onForeignKeyClick($event)\"\n (PageChange)=\"onPageChange($event)\"\n >\n </mj-entity-data-grid>\n\n <!-- NOTE: Export is NOT handled here — mj-entity-data-grid hosts its OWN export dialog\n (its onExportClick opens it with formats/sampling via ExportService). Adding a second\n dialog here produced two stacked export dialogs. The grid owns export self-contained. -->\n\n <!-- Self-contained Add-to-List dialog (Generic) — owned by this wrapper, never bubbles up. -->\n @if (listManagementConfig) {\n <mj-list-management-dialog\n [Provider]=\"Provider\"\n [visible]=\"showListManagementDialog\"\n [config]=\"listManagementConfig\"\n (complete)=\"onListManagementComplete($event)\"\n (cancel)=\"onListManagementCancel()\"\n >\n </mj-list-management-dialog>\n }\n\n <!-- Self-contained Delete confirmation (Generic) — owned by this wrapper, never bubbles up. -->\n <mj-ev-confirm-dialog\n [IsOpen]=\"showDeleteConfirm\"\n Title=\"Delete Records\"\n [Message]=\"deleteConfirmMessage\"\n DetailMessage=\"This action cannot be undone.\"\n ConfirmText=\"Delete\"\n ConfirmStyle=\"danger\"\n Icon=\"fa-solid fa-trash\"\n (Confirmed)=\"onDeleteConfirmed()\"\n (Cancelled)=\"onDeleteCancelled()\"\n >\n </mj-ev-confirm-dialog>\n `,\n styles: [\n `\n :host {\n display: block;\n height: 100%;\n }\n `,\n ],\n})\nexport class GridViewRendererComponent extends BaseAngularComponent implements IViewRenderer<GridViewConfig> {\n /** Change detection ref used to flush dialog visibility toggles driven by grid events. */\n private cdr = inject(ChangeDetectorRef);\n\n // ---- IViewRenderer core inputs (camelCase per the host contract) ----\n\n /** The entity whose records are being rendered. Used to build default params + resolve selection. */\n @Input() entity: EntityInfo | null = null;\n\n /** The records to render (already loaded / filtered / paged by the host). Fed into `[Data]`. */\n @Input() records: Record<string, unknown>[] = [];\n\n /** Primary-key string of the currently selected record, if any. */\n @Input() selectedRecordId: string | null = null;\n\n /** Active filter text — passed through for the grid's cell highlighting. */\n @Input() filterText: string | null = null;\n\n /** Opaque per-view configuration. Seeds the grid bindings; mutated + re-emitted on grid changes. */\n @Input() config: GridViewConfig = {};\n\n // ---- IViewRenderer generic data-context inputs ----\n\n /** Total record count across all pages, for the grid's pager. Fed into `[TotalRowCount]`. */\n @Input() totalRecordCount?: number;\n\n /** One-based current page the host is showing. Fed into `[PagerPageNumber]` (already 1-based). */\n @Input() page?: number;\n\n /** Page size the host is using — fallback when `config.pageSize` is absent. */\n @Input() pageSize?: number;\n\n /** Whether the host is currently (re)loading the record set. Accepted per contract; unused here. */\n @Input() isLoading?: boolean;\n\n // ---- IViewRenderer outputs (generic + navigation channels only) ----\n\n /** Emitted when a row is single-clicked — payload is the raw record object (host builds the key). */\n @Output() recordSelected = new EventEmitter<unknown>();\n\n /** Emitted when a row is double-clicked — payload is the raw record object (host builds the key). */\n @Output() recordOpened = new EventEmitter<unknown>();\n\n /** Emitted when this renderer mutates its opaque {@link config} (sort / grid-state persistence). */\n @Output() configChanged = new EventEmitter<GridViewConfig>();\n\n /** Generic data-access channel: ask the host to re-load with different sort / page. */\n @Output() dataRequest = new EventEmitter<ViewDataRequest>();\n\n /**\n * NAVIGATION: open a related record on a (possibly different) entity from a foreign-key cell click.\n * Routing lives in the outer app, so this is one of the few signals that legitimately bubbles up.\n */\n @Output() openRelatedRecordRequested = new EventEmitter<ViewRelatedRecordNavigation>();\n\n /** NAVIGATION: create a new record of the current entity (grid \"New\" button). Bubbles up for routing. */\n @Output() createRecordRequested = new EventEmitter<void>();\n\n /**\n * Reference to the hosted grid. Currently only retained for parity / future selection resolution;\n * selection is mapped from the {@link records} input rather than read from the grid, per contract.\n */\n @ViewChild('grid') protected grid?: EntityDataGridComponent;\n\n // ================================================================\n // Self-contained dialog state (never surfaced to the host)\n // ================================================================\n // NOTE: Export has no state here — mj-entity-data-grid owns its export dialog.\n\n /** Whether the add-to-list dialog is visible. Toggled internally by {@link onAddToListRequested}. */\n protected showListManagementDialog = false;\n\n /** Config fed into `<mj-list-management-dialog>`. Built from the entity + selected records. */\n protected listManagementConfig: ListManagementDialogConfig | null = null;\n\n /** Whether the delete-confirmation dialog is visible. Toggled internally by {@link onDeleteButtonClick}. */\n protected showDeleteConfirm = false;\n\n /** Records staged for deletion while the confirm dialog is open. */\n private pendingDeleteRecords: Record<string, unknown>[] = [];\n\n /** Dynamic message for the delete-confirmation dialog (reflects the staged record count). */\n protected deleteConfirmMessage = 'Are you sure you want to delete the selected records?';\n\n // ================================================================\n // Effective binding accessors — seed grid inputs from config + defaults\n // ================================================================\n\n /** Effective toolbar visibility — defaults to `true` when not set in config. */\n get effectiveShowToolbar(): boolean {\n return this.config.showToolbar ?? true;\n }\n\n /** Effective selection mode — defaults to `'checkbox'` when not set in config. */\n get effectiveSelectionMode(): GridSelectionMode {\n return this.config.selectionMode ?? 'checkbox';\n }\n\n /** Effective add-to-list button visibility — defaults to `true` when not set in config. */\n get effectiveShowAddToListButton(): boolean {\n return this.config.showAddToListButton ?? true;\n }\n\n /** Effective pager visibility — defaults to `true` when not set in config. */\n get effectiveShowPager(): boolean {\n return this.config.showPager ?? true;\n }\n\n /** Effective page size — config wins, else the generic `pageSize` input, else the grid's own default. */\n get effectivePageSize(): number {\n return this.config.pageSize ?? this.pageSize ?? 100;\n }\n\n /**\n * Effective RunViewParams for the grid. Uses `config.params` when supplied; otherwise builds a\n * minimal dynamic-view params object from {@link entity}. Returns `null` when no entity is known\n * yet (the grid renders empty until the host provides one).\n */\n get effectiveParams(): RunViewParams | null {\n if (this.config.params) {\n return this.config.params;\n }\n if (this.entity) {\n return { EntityName: this.entity.Name };\n }\n return null;\n }\n\n // ================================================================\n // Navigation + generic coordination output mapping\n // ================================================================\n\n /**\n * Row single-click → {@link recordSelected}. Extracts the raw record (`event.row`) so the host\n * builds the composite key itself, matching the other renderers.\n */\n onAfterRowClick(event: AfterRowClickEventArgs): void {\n if (event.row) {\n this.recordSelected.emit(event.row);\n }\n }\n\n /** Row double-click → {@link recordOpened} (NAVIGATION), emitting the raw record object. */\n onAfterRowDoubleClick(event: AfterRowDoubleClickEventArgs): void {\n if (event.row) {\n this.recordOpened.emit(event.row);\n }\n }\n\n /**\n * Sort change → both generic coordination channels:\n * 1. {@link dataRequest} with the generic `sort` shape so the host re-loads with a new OrderBy.\n * 2. persists the sort into `config.gridState.sortSettings` and emits {@link configChanged} so\n * the grid's sort survives view reloads via the opaque config channel.\n */\n onAfterSort(event: AfterSortEventArgs): void {\n const sort = (event.newSortState ?? []).map((s) => ({ field: s.field, direction: s.direction }));\n this.dataRequest.emit({ sort });\n\n const gridState: ViewGridState = { ...(this.config.gridState ?? {}) };\n gridState.sortSettings = (event.newSortState ?? []).map((s) => ({ field: s.field, dir: s.direction }));\n this.config = { ...this.config, gridState };\n this.configChanged.emit(this.config);\n }\n\n /**\n * Generic grid-state change (column resize / reorder / visibility) → merge the grid's updated\n * {@link ViewGridState} into the opaque config and emit {@link configChanged}; the host persists\n * the blob verbatim. No `dataRequest` here — column changes don't alter the loaded record set.\n */\n onGridStateChanged(event: GridStateChangedEvent): void {\n this.config = { ...this.config, gridState: event.gridState };\n this.configChanged.emit(this.config);\n }\n\n /**\n * Selection change → kept INTERNAL. The grid drives its own add-to-list from the selection, so the\n * wrapper has no need to surface it. We intentionally do not bubble selection anywhere.\n */\n onSelectionChange(_selectedKeys: string[]): void {\n // No-op: selection is internal to the grid + this wrapper's add-to-list. It never bubbles up.\n }\n\n /**\n * Foreign-key link click → {@link openRelatedRecordRequested} (NAVIGATION). Maps the grid's\n * {@link ForeignKeyClickEvent} (which carries the related entity + the FK value) onto the generic\n * {@link ViewRelatedRecordNavigation} the container forwards to the outer app for routing. The\n * related entity name is taken from the event when present, else resolved from the metadata by ID.\n */\n onForeignKeyClick(event: ForeignKeyClickEvent): void {\n const entityName = event.relatedEntityName ?? this.resolveEntityNameById(event.relatedEntityId);\n if (!entityName) {\n return;\n }\n this.openRelatedRecordRequested.emit({ entityName, recordKey: event.recordId });\n }\n\n /** New button → {@link createRecordRequested} (NAVIGATION) — opening the create form is routing. */\n onNewButtonClick(): void {\n this.createRecordRequested.emit();\n }\n\n /**\n * Pager navigation → generic {@link dataRequest}. Maps the grid's {@link PageChangeEvent}\n * (`PageNumber` is already 1-based, `PageSize`) onto the generic `{ page, pageSize }` shape the\n * host honors against its own RunView.\n */\n onPageChange(event: PageChangeEvent): void {\n this.dataRequest.emit({ page: event.PageNumber, pageSize: event.PageSize });\n }\n\n // ================================================================\n // Self-contained: Refresh\n // ================================================================\n\n /**\n * Refresh button → re-emit {@link dataRequest} so the host reloads the current page. This is\n * generic container ↔ plug-in coordination (a data-access request), NOT a feature event surfaced\n * to the outer app.\n */\n onRefreshButtonClick(): void {\n this.dataRequest.emit(this.currentPageDataRequest());\n }\n\n // ================================================================\n // Export: handled entirely by mj-entity-data-grid (its onExportClick opens its own export dialog\n // via ExportService). This wrapper intentionally does NOT host an export dialog — doing so produced\n // two stacked dialogs. Nothing to do here.\n // ================================================================\n\n // ================================================================\n // Self-contained: Add to List (hosts <mj-list-management-dialog>)\n // ================================================================\n\n /**\n * Add-to-list button → build a {@link ListManagementDialogConfig} from the entity + the records the\n * grid supplied, then open the Generic list-management dialog. The dialog persists membership\n * changes itself — nothing bubbles up. Mirrors the config construction the legacy host did in\n * `data-explorer-dashboard`'s `onAddToListRequested()`.\n */\n onAddToListRequested(event: { entityInfo: EntityInfo; records: Record<string, unknown>[]; recordIds: string[] }): void {\n const entity = event.entityInfo ?? this.entity;\n if (!entity || !event.records || event.records.length === 0) {\n return;\n }\n\n const recordDisplayNames = event.records.map((record) => this.getRecordDisplayName(record, entity));\n const recordIds = this.buildRawRecordIds(event.records, entity);\n if (recordIds.length === 0) {\n return;\n }\n\n const recordCount = event.records.length;\n const dialogTitle = recordCount === 1 ? `Manage Lists for \"${recordDisplayNames[0]}\"` : `Add ${recordCount} Records to List`;\n\n this.listManagementConfig = {\n mode: 'manage',\n entityId: entity.ID,\n entityName: entity.Name,\n recordIds,\n recordDisplayNames,\n allowCreate: true,\n allowRemove: recordCount === 1,\n showMembership: recordCount === 1,\n dialogTitle,\n };\n this.showListManagementDialog = true;\n this.cdr.detectChanges();\n }\n\n /** List-management dialog completed (membership changes applied) → tear down state. */\n onListManagementComplete(_result: ListManagementResult): void {\n this.showListManagementDialog = false;\n this.listManagementConfig = null;\n this.cdr.detectChanges();\n }\n\n /** List-management dialog cancelled → tear down state. */\n onListManagementCancel(): void {\n this.showListManagementDialog = false;\n this.listManagementConfig = null;\n this.cdr.detectChanges();\n }\n\n /**\n * Resolve a human-friendly display name for a record using the entity's NameField, falling back to\n * the composite-key string. Mirrors the legacy host's display-name resolution.\n */\n private getRecordDisplayName(record: Record<string, unknown>, entity: EntityInfo): string {\n if (entity.NameField) {\n const nameValue = record[entity.NameField.Name];\n if (nameValue != null) {\n return String(nameValue);\n }\n }\n return buildPkString(record, entity) || 'Unknown';\n }\n\n /**\n * Build the list of RAW primary-key values (not concatenated composite-key strings) used by list\n * membership matching. Mirrors the legacy host, which deliberately extracts the first PK field's\n * raw value so it matches how List Details store records.\n */\n private buildRawRecordIds(records: Record<string, unknown>[], entity: EntityInfo): string[] {\n const pkFieldName = entity.PrimaryKeys[0]?.Name;\n if (!pkFieldName) {\n return [];\n }\n return records\n .map((record) => {\n const value = record[pkFieldName];\n return value == null ? '' : String(value);\n })\n .filter((id) => id !== '');\n }\n\n // ================================================================\n // Self-contained: Delete (hosts <mj-ev-confirm-dialog> + MJ entity layer)\n // ================================================================\n\n /**\n * Delete button → stage the records and open the Generic confirm dialog. The actual delete happens\n * in {@link onDeleteConfirmed} after the user confirms — nothing bubbles up.\n */\n onDeleteButtonClick(records: Record<string, unknown>[]): void {\n if (!records || records.length === 0) {\n return;\n }\n this.pendingDeleteRecords = records;\n const count = records.length;\n this.deleteConfirmMessage = count === 1 ? 'Are you sure you want to delete this record?' : `Are you sure you want to delete these ${count} records?`;\n this.showDeleteConfirm = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Delete confirmed → delete each staged record through the MJ entity layer\n * (`ProviderToUse.GetEntityObject(name, compositeKey, user)` → `Delete`), checking the boolean\n * result and surfacing failures via {@link LogError}. After deletion, re-request the current page\n * so the host reloads. Self-contained — no feature event leaves the wrapper.\n */\n async onDeleteConfirmed(): Promise<void> {\n this.showDeleteConfirm = false;\n const entity = this.entity;\n const records = this.pendingDeleteRecords;\n this.pendingDeleteRecords = [];\n\n if (!entity || records.length === 0) {\n return;\n }\n\n let anyDeleted = false;\n const provider = this.ProviderToUse;\n const user = provider.CurrentUser;\n\n for (const record of records) {\n const key = buildCompositeKey(record, entity);\n try {\n // The (name, key, user) overload instantiates AND loads in one call (throws if it can't load).\n const obj = await provider.GetEntityObject(entity.Name, key, user);\n const deleted = await obj.Delete();\n if (deleted) {\n anyDeleted = true;\n } else {\n LogError(`Delete failed: ${obj.LatestResult?.CompleteMessage ?? 'unknown error'}`);\n }\n } catch (err) {\n LogError(`Delete failed for ${entity.Name} (${key.ToString()}): ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n if (anyDeleted) {\n // Re-request the current page so the host reloads the (now smaller) record set.\n this.dataRequest.emit(this.currentPageDataRequest());\n }\n this.cdr.detectChanges();\n }\n\n /** Delete cancelled → discard the staged records and close the confirm dialog. */\n onDeleteCancelled(): void {\n this.showDeleteConfirm = false;\n this.pendingDeleteRecords = [];\n this.cdr.detectChanges();\n }\n\n // ================================================================\n // Helpers\n // ================================================================\n\n /** Build a {@link ViewDataRequest} that re-requests the host's current page/pageSize, if known. */\n private currentPageDataRequest(): ViewDataRequest {\n const req: ViewDataRequest = {};\n if (this.page != null) {\n req.page = this.page;\n }\n const ps = this.config.pageSize ?? this.pageSize;\n if (ps != null) {\n req.pageSize = ps;\n }\n return req;\n }\n\n /**\n * Resolve an entity's name from its ID via the active provider's metadata. Used when a foreign-key\n * click event omits the related entity name and only carries its ID.\n */\n private resolveEntityNameById(entityId: string): string | null {\n if (!entityId) {\n return null;\n }\n const match = this.ProviderToUse.Entities.find((e) => UUIDsEqual(e.ID, entityId));\n return match ? match.Name : null;\n }\n}\n\n/**\n * Tree-shaking guard. Force-references this renderer so bundlers (ESBuild/Vite) don't drop the\n * component in builds that only mount it dynamically via the ClassFactory/descriptor. Mirrors the\n * Cards/Cluster renderers' load guards; the parent wires this into a barrel/module load path.\n */\nexport function LoadGridViewRenderer(): void {\n // no-op; presence prevents tree-shaking of this component\n}\n"]}
@@ -0,0 +1,135 @@
1
+ import { EventEmitter, OnInit } from '@angular/core';
2
+ import { EntityInfo } from '@memberjunction/core';
3
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
4
+ import { MapRenderMode, MapDisplayState, MapMarkerClickEvent } from '@memberjunction/ng-map-view';
5
+ import { IViewRenderer, ViewDataRequest } from '../view-type.contracts';
6
+ import * as i0 from "@angular/core";
7
+ /**
8
+ * Opaque per-view configuration for the Map view type.
9
+ *
10
+ * The host stores and round-trips this blob verbatim against the active `ViewTypeID` and never
11
+ * inspects it — only this renderer reads/writes it. It carries the two pieces of map state that
12
+ * should persist with the view: the render mode (point / boundary / choropleth / heatmap) and the
13
+ * last display state (zoom / center / clustering / choropleth options). Both are optional so a
14
+ * freshly-created Map view starts from sensible defaults.
15
+ */
16
+ export interface MapViewConfig {
17
+ /** The map's render mode. Defaults to `'point'` when unset (see {@link MapViewRendererComponent.activeRenderMode}). */
18
+ renderMode?: MapRenderMode;
19
+ /** The map's last persisted display state (zoom, center, clustering, choropleth options). */
20
+ displayState?: MapDisplayState;
21
+ }
22
+ /**
23
+ * MapViewRendererComponent
24
+ * ------------------------
25
+ * The Map **view type** renderer — a thin {@link IViewRenderer} adapter that hosts the existing
26
+ * {@link MapViewComponent} (`<mj-map-view>`) inside the entity-viewer's pluggable view-type system.
27
+ *
28
+ * **The container has ZERO knowledge of maps.** The host feeds this renderer only the generic
29
+ * {@link IViewRenderer} surface (`entity` / `records` / `totalRecordCount` / `config` / …) and
30
+ * listens only to the generic outputs (`recordSelected` / `configChanged` / `dataRequest` / …).
31
+ * Everything map-specific is encapsulated here:
32
+ *
33
+ * - The map's **render mode + display state** live inside the opaque {@link MapViewConfig} blob.
34
+ * The host persists that blob verbatim against the active `ViewTypeID` and never reads it; this
35
+ * renderer seeds `<mj-map-view>` from it and writes changes back via `configChanged`.
36
+ * - The "maps need the full record set" requirement is expressed through the **generic
37
+ * {@link IViewRenderer.dataRequest} channel** as `{ loadAll: true }` — the container honors the
38
+ * request (loads all records up to its safety cap) without knowing it came from a map.
39
+ *
40
+ * **Why import `MapViewModule` rather than `MapViewComponent` directly:** {@link MapViewComponent}
41
+ * is an NgModule-declared (`standalone: false`) component, so Angular forbids placing it directly
42
+ * in a standalone component's `imports` array (NG6008). The supported way for a standalone
43
+ * component to consume a non-standalone component is to import the NgModule that exports it — here
44
+ * {@link MapViewModule}. {@link MapViewComponent} is still imported above so its `@Input`/`@Output`
45
+ * types stay referenced and the file documents exactly which component it adapts. This mirrors the
46
+ * sibling `CardsViewRendererComponent`'s approach.
47
+ *
48
+ * **Marker → record mapping:** `<mj-map-view>` emits the rich {@link MapMarkerClickEvent}
49
+ * (`{ RecordID, Latitude, Longitude, Record }`), but the host's dynamic renderer handler expects
50
+ * the **raw record** and builds the composite key itself. This adapter therefore extracts
51
+ * `.Record` and re-emits just that object via `recordSelected`, matching the other plug-in
52
+ * renderers (Cards/Cluster emit raw record objects).
53
+ *
54
+ * Inputs use the camelCase names mandated by the {@link IViewRenderer} contract (the host binds
55
+ * them by those exact names), rather than MJ's usual PascalCase for public members — mirroring the
56
+ * Cards and Cluster renderers.
57
+ */
58
+ export declare class MapViewRendererComponent extends BaseAngularComponent implements IViewRenderer<MapViewConfig>, OnInit {
59
+ /** The entity whose records are being mapped. The map requires an entity; when null an empty state renders. */
60
+ entity: EntityInfo | null;
61
+ /** The records to render as map markers (loaded/filtered by the host). */
62
+ records: Record<string, unknown>[];
63
+ /** Primary-key string of the currently selected record, if any. Unused by the map view today. */
64
+ selectedRecordId: string | null;
65
+ /** Active filter text. Unused by the map view today (records are already filtered by the host). */
66
+ filterText: string | null;
67
+ private _config;
68
+ /**
69
+ * The opaque per-view configuration. Setting it re-derives the {@link activeRenderMode} and
70
+ * {@link activeDisplayState} that seed `<mj-map-view>`.
71
+ */
72
+ set config(value: MapViewConfig);
73
+ get config(): MapViewConfig;
74
+ /**
75
+ * The total number of records the host's query would return — bound to `<mj-map-view>`'s
76
+ * `TotalRecordCount` so the map can convey when markers are a capped subset.
77
+ */
78
+ totalRecordCount?: number;
79
+ /** One-based current page of {@link records} when the host is paginating. Unused by the map view. */
80
+ page?: number;
81
+ /** Page size the host is using. Unused by the map view. */
82
+ pageSize?: number;
83
+ /** Whether the host is currently (re)loading the record set. Unused by the map view today. */
84
+ isLoading?: boolean;
85
+ /** Emitted when a marker is clicked — payload is the raw record object (the marker's `.Record`). */
86
+ recordSelected: EventEmitter<unknown>;
87
+ /**
88
+ * Required by {@link IViewRenderer}; the map view has no distinct "open" gesture, so this never
89
+ * emits. Declared so the host's uniform output subscription is satisfied.
90
+ */
91
+ recordOpened: EventEmitter<unknown>;
92
+ /**
93
+ * Emitted when the user changes the render mode or pans/zooms the map. The host persists the
94
+ * updated {@link MapViewConfig} blob verbatim against the active `ViewTypeID`.
95
+ */
96
+ configChanged: EventEmitter<MapViewConfig>;
97
+ /**
98
+ * The generic data-access channel. On init this emits `{ loadAll: true }` so the container loads
99
+ * the full record set — maps need every record to plot, not a single page — requested without the
100
+ * container knowing it came from a map.
101
+ */
102
+ dataRequest: EventEmitter<ViewDataRequest>;
103
+ /** The render mode bound to `<mj-map-view>`, derived from {@link config} (defaults to `'point'`). */
104
+ activeRenderMode: MapRenderMode;
105
+ /** The display state bound to `<mj-map-view>`, derived from {@link config} (null when unset). */
106
+ activeDisplayState: Partial<MapDisplayState> | null;
107
+ ngOnInit(): void;
108
+ /** Re-derive the map's render mode + display state from the current opaque {@link config}. */
109
+ private applyConfig;
110
+ /**
111
+ * Relay `<mj-map-view>`'s marker click, normalizing to the raw record the host expects (the host
112
+ * builds the composite key itself from the record + entity).
113
+ */
114
+ onMarkerClick(event: MapMarkerClickEvent): void;
115
+ /**
116
+ * Persist a render-mode change into the opaque {@link config} and notify the host. The host
117
+ * stores the blob verbatim; it has no knowledge that `renderMode` means anything map-specific.
118
+ */
119
+ onRenderModeChange(mode: MapRenderMode): void;
120
+ /**
121
+ * Persist a display-state change (pan / zoom / clustering / choropleth options) into the opaque
122
+ * {@link config} and notify the host. This fires continuously as the user pans/zooms; that's
123
+ * fine — the host debounces persistence of the config blob.
124
+ */
125
+ onDisplayStateChange(state: MapDisplayState): void;
126
+ static ɵfac: i0.ɵɵFactoryDeclaration<MapViewRendererComponent, never>;
127
+ static ɵcmp: i0.ɵɵComponentDeclaration<MapViewRendererComponent, "mj-map-view-renderer", never, { "entity": { "alias": "entity"; "required": false; }; "records": { "alias": "records"; "required": false; }; "selectedRecordId": { "alias": "selectedRecordId"; "required": false; }; "filterText": { "alias": "filterText"; "required": false; }; "config": { "alias": "config"; "required": false; }; "totalRecordCount": { "alias": "totalRecordCount"; "required": false; }; "page": { "alias": "page"; "required": false; }; "pageSize": { "alias": "pageSize"; "required": false; }; "isLoading": { "alias": "isLoading"; "required": false; }; }, { "recordSelected": "recordSelected"; "recordOpened": "recordOpened"; "configChanged": "configChanged"; "dataRequest": "dataRequest"; }, never, never, false, never>;
128
+ }
129
+ /**
130
+ * Tree-shaking guard. Force-references this renderer so bundlers (ESBuild/Vite) don't drop the
131
+ * component in builds that only mount it dynamically via the ClassFactory/descriptor. Mirrors the
132
+ * Cards and Cluster renderers' load guards; the parent wires this into a barrel/module load path.
133
+ */
134
+ export declare function LoadMapViewRenderer(): void;
135
+ //# sourceMappingURL=map-view-renderer.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-view-renderer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/view-types/renderers/map-view-renderer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAqB,MAAM,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAEL,aAAa,EACb,eAAe,EACf,mBAAmB,EACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;;AAExE;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,uHAAuH;IACvH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,6FAA6F;IAC7F,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAgDa,wBAAyB,SAAQ,oBAAqB,YAAW,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM;IAGhH,+GAA+G;IACtG,MAAM,EAAE,UAAU,GAAG,IAAI,CAAQ;IAE1C,0EAA0E;IACjE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAM;IAEjD,iGAAiG;IACxF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEhD,mGAAmG;IAC1F,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE1C,OAAO,CAAC,OAAO,CAAqB;IACpC;;;OAGG;IACH,IACI,MAAM,CAAC,KAAK,EAAE,aAAa,EAG9B;IACD,IAAI,MAAM,IAAI,aAAa,CAE1B;IAED;;;OAGG;IACM,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAEnC,qGAAqG;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB,2DAA2D;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,8FAA8F;IACrF,SAAS,CAAC,EAAE,OAAO,CAAC;IAI7B,oGAAoG;IAC1F,cAAc,wBAA+B;IAEvD;;;OAGG;IACO,YAAY,wBAA+B;IAErD;;;OAGG;IACO,aAAa,8BAAqC;IAE5D;;;;OAIG;IACO,WAAW,gCAAuC;IAI5D,qGAAqG;IAC9F,gBAAgB,EAAE,aAAa,CAAW;IAEjD,iGAAiG;IAC1F,kBAAkB,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAQ;IAElE,QAAQ,IAAI,IAAI;IAOhB,8FAA8F;IAC9F,OAAO,CAAC,WAAW;IAKnB;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAI/C;;;OAGG;IACH,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAM7C;;;;OAIG;IACH,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;yCAhHvC,wBAAwB;2CAAxB,wBAAwB;CAqHpC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -0,0 +1,216 @@
1
+ import { Component, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core';
2
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@memberjunction/ng-map-view";
5
+ function MapViewRendererComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
6
+ const _r1 = i0.ɵɵgetCurrentView();
7
+ i0.ɵɵelementStart(0, "mj-map-view", 2);
8
+ i0.ɵɵlistener("MarkerClick", function MapViewRendererComponent_Conditional_0_Template_mj_map_view_MarkerClick_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onMarkerClick($event)); })("RenderModeChange", function MapViewRendererComponent_Conditional_0_Template_mj_map_view_RenderModeChange_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onRenderModeChange($event)); })("DisplayStateChange", function MapViewRendererComponent_Conditional_0_Template_mj_map_view_DisplayStateChange_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDisplayStateChange($event)); });
9
+ i0.ɵɵelementEnd();
10
+ } if (rf & 2) {
11
+ const ctx_r1 = i0.ɵɵnextContext();
12
+ i0.ɵɵproperty("Entity", ctx_r1.entity)("Records", ctx_r1.records)("TotalRecordCount", ctx_r1.totalRecordCount ?? 0)("RenderMode", ctx_r1.activeRenderMode)("DisplayState", ctx_r1.activeDisplayState);
13
+ } }
14
+ function MapViewRendererComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
15
+ i0.ɵɵelementStart(0, "div", 1);
16
+ i0.ɵɵelement(1, "i", 3);
17
+ i0.ɵɵelementStart(2, "span");
18
+ i0.ɵɵtext(3, "No entity selected to map.");
19
+ i0.ɵɵelementEnd()();
20
+ } }
21
+ /**
22
+ * MapViewRendererComponent
23
+ * ------------------------
24
+ * The Map **view type** renderer — a thin {@link IViewRenderer} adapter that hosts the existing
25
+ * {@link MapViewComponent} (`<mj-map-view>`) inside the entity-viewer's pluggable view-type system.
26
+ *
27
+ * **The container has ZERO knowledge of maps.** The host feeds this renderer only the generic
28
+ * {@link IViewRenderer} surface (`entity` / `records` / `totalRecordCount` / `config` / …) and
29
+ * listens only to the generic outputs (`recordSelected` / `configChanged` / `dataRequest` / …).
30
+ * Everything map-specific is encapsulated here:
31
+ *
32
+ * - The map's **render mode + display state** live inside the opaque {@link MapViewConfig} blob.
33
+ * The host persists that blob verbatim against the active `ViewTypeID` and never reads it; this
34
+ * renderer seeds `<mj-map-view>` from it and writes changes back via `configChanged`.
35
+ * - The "maps need the full record set" requirement is expressed through the **generic
36
+ * {@link IViewRenderer.dataRequest} channel** as `{ loadAll: true }` — the container honors the
37
+ * request (loads all records up to its safety cap) without knowing it came from a map.
38
+ *
39
+ * **Why import `MapViewModule` rather than `MapViewComponent` directly:** {@link MapViewComponent}
40
+ * is an NgModule-declared (`standalone: false`) component, so Angular forbids placing it directly
41
+ * in a standalone component's `imports` array (NG6008). The supported way for a standalone
42
+ * component to consume a non-standalone component is to import the NgModule that exports it — here
43
+ * {@link MapViewModule}. {@link MapViewComponent} is still imported above so its `@Input`/`@Output`
44
+ * types stay referenced and the file documents exactly which component it adapts. This mirrors the
45
+ * sibling `CardsViewRendererComponent`'s approach.
46
+ *
47
+ * **Marker → record mapping:** `<mj-map-view>` emits the rich {@link MapMarkerClickEvent}
48
+ * (`{ RecordID, Latitude, Longitude, Record }`), but the host's dynamic renderer handler expects
49
+ * the **raw record** and builds the composite key itself. This adapter therefore extracts
50
+ * `.Record` and re-emits just that object via `recordSelected`, matching the other plug-in
51
+ * renderers (Cards/Cluster emit raw record objects).
52
+ *
53
+ * Inputs use the camelCase names mandated by the {@link IViewRenderer} contract (the host binds
54
+ * them by those exact names), rather than MJ's usual PascalCase for public members — mirroring the
55
+ * Cards and Cluster renderers.
56
+ */
57
+ export class MapViewRendererComponent extends BaseAngularComponent {
58
+ // ---- IViewRenderer inputs (camelCase per the host contract) ----
59
+ /** The entity whose records are being mapped. The map requires an entity; when null an empty state renders. */
60
+ entity = null;
61
+ /** The records to render as map markers (loaded/filtered by the host). */
62
+ records = [];
63
+ /** Primary-key string of the currently selected record, if any. Unused by the map view today. */
64
+ selectedRecordId = null;
65
+ /** Active filter text. Unused by the map view today (records are already filtered by the host). */
66
+ filterText = null;
67
+ _config = {};
68
+ /**
69
+ * The opaque per-view configuration. Setting it re-derives the {@link activeRenderMode} and
70
+ * {@link activeDisplayState} that seed `<mj-map-view>`.
71
+ */
72
+ set config(value) {
73
+ this._config = value ?? {};
74
+ this.applyConfig();
75
+ }
76
+ get config() {
77
+ return this._config;
78
+ }
79
+ /**
80
+ * The total number of records the host's query would return — bound to `<mj-map-view>`'s
81
+ * `TotalRecordCount` so the map can convey when markers are a capped subset.
82
+ */
83
+ totalRecordCount;
84
+ /** One-based current page of {@link records} when the host is paginating. Unused by the map view. */
85
+ page;
86
+ /** Page size the host is using. Unused by the map view. */
87
+ pageSize;
88
+ /** Whether the host is currently (re)loading the record set. Unused by the map view today. */
89
+ isLoading;
90
+ // ---- IViewRenderer outputs ----
91
+ /** Emitted when a marker is clicked — payload is the raw record object (the marker's `.Record`). */
92
+ recordSelected = new EventEmitter();
93
+ /**
94
+ * Required by {@link IViewRenderer}; the map view has no distinct "open" gesture, so this never
95
+ * emits. Declared so the host's uniform output subscription is satisfied.
96
+ */
97
+ recordOpened = new EventEmitter();
98
+ /**
99
+ * Emitted when the user changes the render mode or pans/zooms the map. The host persists the
100
+ * updated {@link MapViewConfig} blob verbatim against the active `ViewTypeID`.
101
+ */
102
+ configChanged = new EventEmitter();
103
+ /**
104
+ * The generic data-access channel. On init this emits `{ loadAll: true }` so the container loads
105
+ * the full record set — maps need every record to plot, not a single page — requested without the
106
+ * container knowing it came from a map.
107
+ */
108
+ dataRequest = new EventEmitter();
109
+ // ---- Render state (seeded from config) ----
110
+ /** The render mode bound to `<mj-map-view>`, derived from {@link config} (defaults to `'point'`). */
111
+ activeRenderMode = 'point';
112
+ /** The display state bound to `<mj-map-view>`, derived from {@link config} (null when unset). */
113
+ activeDisplayState = null;
114
+ ngOnInit() {
115
+ // Maps need the complete record set, not a single page. Request it through the generic
116
+ // data-access channel — the container honors `{ loadAll: true }` without any map-specific
117
+ // branching. Done after inputs are wired (the host sets inputs via setInput before ngOnInit).
118
+ this.dataRequest.emit({ loadAll: true });
119
+ }
120
+ /** Re-derive the map's render mode + display state from the current opaque {@link config}. */
121
+ applyConfig() {
122
+ this.activeRenderMode = this._config.renderMode ?? 'point';
123
+ this.activeDisplayState = this._config.displayState ?? null;
124
+ }
125
+ /**
126
+ * Relay `<mj-map-view>`'s marker click, normalizing to the raw record the host expects (the host
127
+ * builds the composite key itself from the record + entity).
128
+ */
129
+ onMarkerClick(event) {
130
+ this.recordSelected.emit(event.Record);
131
+ }
132
+ /**
133
+ * Persist a render-mode change into the opaque {@link config} and notify the host. The host
134
+ * stores the blob verbatim; it has no knowledge that `renderMode` means anything map-specific.
135
+ */
136
+ onRenderModeChange(mode) {
137
+ this._config = { ...this._config, renderMode: mode };
138
+ this.activeRenderMode = mode;
139
+ this.configChanged.emit(this._config);
140
+ }
141
+ /**
142
+ * Persist a display-state change (pan / zoom / clustering / choropleth options) into the opaque
143
+ * {@link config} and notify the host. This fires continuously as the user pans/zooms; that's
144
+ * fine — the host debounces persistence of the config blob.
145
+ */
146
+ onDisplayStateChange(state) {
147
+ this._config = { ...this._config, displayState: state };
148
+ this.activeDisplayState = state;
149
+ this.configChanged.emit(this._config);
150
+ }
151
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMapViewRendererComponent_BaseFactory; return function MapViewRendererComponent_Factory(__ngFactoryType__) { return (ɵMapViewRendererComponent_BaseFactory || (ɵMapViewRendererComponent_BaseFactory = i0.ɵɵgetInheritedFactory(MapViewRendererComponent)))(__ngFactoryType__ || MapViewRendererComponent); }; })();
152
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MapViewRendererComponent, selectors: [["mj-map-view-renderer"]], inputs: { entity: "entity", records: "records", selectedRecordId: "selectedRecordId", filterText: "filterText", config: "config", totalRecordCount: "totalRecordCount", page: "page", pageSize: "pageSize", isLoading: "isLoading" }, outputs: { recordSelected: "recordSelected", recordOpened: "recordOpened", configChanged: "configChanged", dataRequest: "dataRequest" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[3, "Entity", "Records", "TotalRecordCount", "RenderMode", "DisplayState"], [1, "map-view-renderer-empty"], [3, "MarkerClick", "RenderModeChange", "DisplayStateChange", "Entity", "Records", "TotalRecordCount", "RenderMode", "DisplayState"], [1, "fa-solid", "fa-map-location-dot"]], template: function MapViewRendererComponent_Template(rf, ctx) { if (rf & 1) {
153
+ i0.ɵɵconditionalCreate(0, MapViewRendererComponent_Conditional_0_Template, 1, 5, "mj-map-view", 0)(1, MapViewRendererComponent_Conditional_1_Template, 4, 0, "div", 1);
154
+ } if (rf & 2) {
155
+ i0.ɵɵconditional(ctx.entity ? 0 : 1);
156
+ } }, dependencies: [i1.MapViewComponent], styles: ["\n :host {\n display: block;\n height: 100%;\n }\n .map-view-renderer-empty {\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n color: var(--mj-text-muted);\n padding: 32px;\n text-align: center;\n }\n .map-view-renderer-empty i {\n font-size: 32px;\n opacity: 0.6;\n }\n "], encapsulation: 2 });
157
+ }
158
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MapViewRendererComponent, [{
159
+ type: Component,
160
+ args: [{ standalone: false, selector: 'mj-map-view-renderer', encapsulation: ViewEncapsulation.None, template: `
161
+ @if (entity) {
162
+ <mj-map-view
163
+ [Entity]="entity"
164
+ [Records]="records"
165
+ [TotalRecordCount]="totalRecordCount ?? 0"
166
+ [RenderMode]="activeRenderMode"
167
+ [DisplayState]="activeDisplayState"
168
+ (MarkerClick)="onMarkerClick($event)"
169
+ (RenderModeChange)="onRenderModeChange($event)"
170
+ (DisplayStateChange)="onDisplayStateChange($event)"
171
+ >
172
+ </mj-map-view>
173
+ } @else {
174
+ <div class="map-view-renderer-empty">
175
+ <i class="fa-solid fa-map-location-dot"></i>
176
+ <span>No entity selected to map.</span>
177
+ </div>
178
+ }
179
+ `, styles: ["\n :host {\n display: block;\n height: 100%;\n }\n .map-view-renderer-empty {\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n color: var(--mj-text-muted);\n padding: 32px;\n text-align: center;\n }\n .map-view-renderer-empty i {\n font-size: 32px;\n opacity: 0.6;\n }\n "] }]
180
+ }], null, { entity: [{
181
+ type: Input
182
+ }], records: [{
183
+ type: Input
184
+ }], selectedRecordId: [{
185
+ type: Input
186
+ }], filterText: [{
187
+ type: Input
188
+ }], config: [{
189
+ type: Input
190
+ }], totalRecordCount: [{
191
+ type: Input
192
+ }], page: [{
193
+ type: Input
194
+ }], pageSize: [{
195
+ type: Input
196
+ }], isLoading: [{
197
+ type: Input
198
+ }], recordSelected: [{
199
+ type: Output
200
+ }], recordOpened: [{
201
+ type: Output
202
+ }], configChanged: [{
203
+ type: Output
204
+ }], dataRequest: [{
205
+ type: Output
206
+ }] }); })();
207
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MapViewRendererComponent, { className: "MapViewRendererComponent", filePath: "src/lib/view-types/renderers/map-view-renderer.component.ts", lineNumber: 112 }); })();
208
+ /**
209
+ * Tree-shaking guard. Force-references this renderer so bundlers (ESBuild/Vite) don't drop the
210
+ * component in builds that only mount it dynamically via the ClassFactory/descriptor. Mirrors the
211
+ * Cards and Cluster renderers' load guards; the parent wires this into a barrel/module load path.
212
+ */
213
+ export function LoadMapViewRenderer() {
214
+ // no-op; presence prevents tree-shaking of this component
215
+ }
216
+ //# sourceMappingURL=map-view-renderer.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-view-renderer.component.js","sourceRoot":"","sources":["../../../../src/lib/view-types/renderers/map-view-renderer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewEncapsulation, OnInit } from '@angular/core';\nimport { EntityInfo } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport {\n MapViewComponent,\n MapRenderMode,\n MapDisplayState,\n MapMarkerClickEvent,\n} from '@memberjunction/ng-map-view';\nimport { IViewRenderer, ViewDataRequest } from '../view-type.contracts';\n\n/**\n * Opaque per-view configuration for the Map view type.\n *\n * The host stores and round-trips this blob verbatim against the active `ViewTypeID` and never\n * inspects it — only this renderer reads/writes it. It carries the two pieces of map state that\n * should persist with the view: the render mode (point / boundary / choropleth / heatmap) and the\n * last display state (zoom / center / clustering / choropleth options). Both are optional so a\n * freshly-created Map view starts from sensible defaults.\n */\nexport interface MapViewConfig {\n /** The map's render mode. Defaults to `'point'` when unset (see {@link MapViewRendererComponent.activeRenderMode}). */\n renderMode?: MapRenderMode;\n /** The map's last persisted display state (zoom, center, clustering, choropleth options). */\n displayState?: MapDisplayState;\n}\n\n/**\n * MapViewRendererComponent\n * ------------------------\n * The Map **view type** renderer — a thin {@link IViewRenderer} adapter that hosts the existing\n * {@link MapViewComponent} (`<mj-map-view>`) inside the entity-viewer's pluggable view-type system.\n *\n * **The container has ZERO knowledge of maps.** The host feeds this renderer only the generic\n * {@link IViewRenderer} surface (`entity` / `records` / `totalRecordCount` / `config` / …) and\n * listens only to the generic outputs (`recordSelected` / `configChanged` / `dataRequest` / …).\n * Everything map-specific is encapsulated here:\n *\n * - The map's **render mode + display state** live inside the opaque {@link MapViewConfig} blob.\n * The host persists that blob verbatim against the active `ViewTypeID` and never reads it; this\n * renderer seeds `<mj-map-view>` from it and writes changes back via `configChanged`.\n * - The \"maps need the full record set\" requirement is expressed through the **generic\n * {@link IViewRenderer.dataRequest} channel** as `{ loadAll: true }` — the container honors the\n * request (loads all records up to its safety cap) without knowing it came from a map.\n *\n * **Why import `MapViewModule` rather than `MapViewComponent` directly:** {@link MapViewComponent}\n * is an NgModule-declared (`standalone: false`) component, so Angular forbids placing it directly\n * in a standalone component's `imports` array (NG6008). The supported way for a standalone\n * component to consume a non-standalone component is to import the NgModule that exports it — here\n * {@link MapViewModule}. {@link MapViewComponent} is still imported above so its `@Input`/`@Output`\n * types stay referenced and the file documents exactly which component it adapts. This mirrors the\n * sibling `CardsViewRendererComponent`'s approach.\n *\n * **Marker → record mapping:** `<mj-map-view>` emits the rich {@link MapMarkerClickEvent}\n * (`{ RecordID, Latitude, Longitude, Record }`), but the host's dynamic renderer handler expects\n * the **raw record** and builds the composite key itself. This adapter therefore extracts\n * `.Record` and re-emits just that object via `recordSelected`, matching the other plug-in\n * renderers (Cards/Cluster emit raw record objects).\n *\n * Inputs use the camelCase names mandated by the {@link IViewRenderer} contract (the host binds\n * them by those exact names), rather than MJ's usual PascalCase for public members — mirroring the\n * Cards and Cluster renderers.\n */\n@Component({\n standalone: false,\n selector: 'mj-map-view-renderer',\n encapsulation: ViewEncapsulation.None,\n template: `\n @if (entity) {\n <mj-map-view\n [Entity]=\"entity\"\n [Records]=\"records\"\n [TotalRecordCount]=\"totalRecordCount ?? 0\"\n [RenderMode]=\"activeRenderMode\"\n [DisplayState]=\"activeDisplayState\"\n (MarkerClick)=\"onMarkerClick($event)\"\n (RenderModeChange)=\"onRenderModeChange($event)\"\n (DisplayStateChange)=\"onDisplayStateChange($event)\"\n >\n </mj-map-view>\n } @else {\n <div class=\"map-view-renderer-empty\">\n <i class=\"fa-solid fa-map-location-dot\"></i>\n <span>No entity selected to map.</span>\n </div>\n }\n `,\n styles: [\n `\n :host {\n display: block;\n height: 100%;\n }\n .map-view-renderer-empty {\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n color: var(--mj-text-muted);\n padding: 32px;\n text-align: center;\n }\n .map-view-renderer-empty i {\n font-size: 32px;\n opacity: 0.6;\n }\n `,\n ],\n})\nexport class MapViewRendererComponent extends BaseAngularComponent implements IViewRenderer<MapViewConfig>, OnInit {\n // ---- IViewRenderer inputs (camelCase per the host contract) ----\n\n /** The entity whose records are being mapped. The map requires an entity; when null an empty state renders. */\n @Input() entity: EntityInfo | null = null;\n\n /** The records to render as map markers (loaded/filtered by the host). */\n @Input() records: Record<string, unknown>[] = [];\n\n /** Primary-key string of the currently selected record, if any. Unused by the map view today. */\n @Input() selectedRecordId: string | null = null;\n\n /** Active filter text. Unused by the map view today (records are already filtered by the host). */\n @Input() filterText: string | null = null;\n\n private _config: MapViewConfig = {};\n /**\n * The opaque per-view configuration. Setting it re-derives the {@link activeRenderMode} and\n * {@link activeDisplayState} that seed `<mj-map-view>`.\n */\n @Input()\n set config(value: MapViewConfig) {\n this._config = value ?? {};\n this.applyConfig();\n }\n get config(): MapViewConfig {\n return this._config;\n }\n\n /**\n * The total number of records the host's query would return — bound to `<mj-map-view>`'s\n * `TotalRecordCount` so the map can convey when markers are a capped subset.\n */\n @Input() totalRecordCount?: number;\n\n /** One-based current page of {@link records} when the host is paginating. Unused by the map view. */\n @Input() page?: number;\n\n /** Page size the host is using. Unused by the map view. */\n @Input() pageSize?: number;\n\n /** Whether the host is currently (re)loading the record set. Unused by the map view today. */\n @Input() isLoading?: boolean;\n\n // ---- IViewRenderer outputs ----\n\n /** Emitted when a marker is clicked — payload is the raw record object (the marker's `.Record`). */\n @Output() recordSelected = new EventEmitter<unknown>();\n\n /**\n * Required by {@link IViewRenderer}; the map view has no distinct \"open\" gesture, so this never\n * emits. Declared so the host's uniform output subscription is satisfied.\n */\n @Output() recordOpened = new EventEmitter<unknown>();\n\n /**\n * Emitted when the user changes the render mode or pans/zooms the map. The host persists the\n * updated {@link MapViewConfig} blob verbatim against the active `ViewTypeID`.\n */\n @Output() configChanged = new EventEmitter<MapViewConfig>();\n\n /**\n * The generic data-access channel. On init this emits `{ loadAll: true }` so the container loads\n * the full record set — maps need every record to plot, not a single page — requested without the\n * container knowing it came from a map.\n */\n @Output() dataRequest = new EventEmitter<ViewDataRequest>();\n\n // ---- Render state (seeded from config) ----\n\n /** The render mode bound to `<mj-map-view>`, derived from {@link config} (defaults to `'point'`). */\n public activeRenderMode: MapRenderMode = 'point';\n\n /** The display state bound to `<mj-map-view>`, derived from {@link config} (null when unset). */\n public activeDisplayState: Partial<MapDisplayState> | null = null;\n\n ngOnInit(): void {\n // Maps need the complete record set, not a single page. Request it through the generic\n // data-access channel — the container honors `{ loadAll: true }` without any map-specific\n // branching. Done after inputs are wired (the host sets inputs via setInput before ngOnInit).\n this.dataRequest.emit({ loadAll: true });\n }\n\n /** Re-derive the map's render mode + display state from the current opaque {@link config}. */\n private applyConfig(): void {\n this.activeRenderMode = this._config.renderMode ?? 'point';\n this.activeDisplayState = this._config.displayState ?? null;\n }\n\n /**\n * Relay `<mj-map-view>`'s marker click, normalizing to the raw record the host expects (the host\n * builds the composite key itself from the record + entity).\n */\n onMarkerClick(event: MapMarkerClickEvent): void {\n this.recordSelected.emit(event.Record);\n }\n\n /**\n * Persist a render-mode change into the opaque {@link config} and notify the host. The host\n * stores the blob verbatim; it has no knowledge that `renderMode` means anything map-specific.\n */\n onRenderModeChange(mode: MapRenderMode): void {\n this._config = { ...this._config, renderMode: mode };\n this.activeRenderMode = mode;\n this.configChanged.emit(this._config);\n }\n\n /**\n * Persist a display-state change (pan / zoom / clustering / choropleth options) into the opaque\n * {@link config} and notify the host. This fires continuously as the user pans/zooms; that's\n * fine — the host debounces persistence of the config blob.\n */\n onDisplayStateChange(state: MapDisplayState): void {\n this._config = { ...this._config, displayState: state };\n this.activeDisplayState = state;\n this.configChanged.emit(this._config);\n }\n}\n\n/**\n * Tree-shaking guard. Force-references this renderer so bundlers (ESBuild/Vite) don't drop the\n * component in builds that only mount it dynamically via the ClassFactory/descriptor. Mirrors the\n * Cards and Cluster renderers' load guards; the parent wires this into a barrel/module load path.\n */\nexport function LoadMapViewRenderer(): void {\n // no-op; presence prevents tree-shaking of this component\n}\n"]}