@memberjunction/ng-core-entity-forms 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 (259) hide show
  1. package/dist/__tests__/model-prediction.logic.test.d.ts +2 -0
  2. package/dist/__tests__/model-prediction.logic.test.d.ts.map +1 -0
  3. package/dist/__tests__/model-prediction.logic.test.js +140 -0
  4. package/dist/__tests__/model-prediction.logic.test.js.map +1 -0
  5. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js +79 -105
  6. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
  7. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js +7 -10
  8. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js.map +1 -1
  9. package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
  10. package/dist/lib/custom/AIAgents/add-action-dialog.component.js +46 -51
  11. package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
  12. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +2 -0
  13. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
  14. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +300 -378
  15. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  16. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +22 -29
  17. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
  18. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +15 -17
  19. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
  20. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +27 -34
  21. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
  22. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +11 -0
  23. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
  24. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +48 -47
  25. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
  26. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +438 -454
  27. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
  28. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +48 -51
  29. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js.map +1 -1
  30. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +253 -282
  31. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
  32. package/dist/lib/custom/Actions/action-execution-log-form.component.js +24 -33
  33. package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
  34. package/dist/lib/custom/Actions/action-form.component.js +263 -311
  35. package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
  36. package/dist/lib/custom/Entities/entity-form.component.d.ts +6 -0
  37. package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
  38. package/dist/lib/custom/Entities/entity-form.component.js +475 -493
  39. package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
  40. package/dist/lib/custom/Lists/list-form.component.js +122 -173
  41. package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
  42. package/dist/lib/custom/Queries/query-form.component.js +190 -248
  43. package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
  44. package/dist/lib/custom/Queries/query-run-dialog.component.js +19 -23
  45. package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
  46. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js +23 -24
  47. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js.map +1 -1
  48. package/dist/lib/custom/Templates/template-param-dialog.component.js +14 -23
  49. package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
  50. package/dist/lib/custom/Tests/test-form.component.js +100 -130
  51. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  52. package/dist/lib/custom/Tests/test-run-form.component.js +187 -205
  53. package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
  54. package/dist/lib/custom/Tests/test-suite-form.component.d.ts +8 -0
  55. package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
  56. package/dist/lib/custom/Tests/test-suite-form.component.js +412 -489
  57. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  58. package/dist/lib/custom/Tests/test-suite-run-form.component.js +100 -126
  59. package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
  60. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +166 -184
  61. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
  62. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +42 -61
  63. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -1
  64. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +8 -17
  65. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
  66. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +0 -2
  67. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
  68. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +183 -188
  69. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
  70. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts +108 -0
  71. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts.map +1 -0
  72. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js +665 -0
  73. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js.map +1 -0
  74. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts +94 -0
  75. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts.map +1 -0
  76. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js +257 -0
  77. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js.map +1 -0
  78. package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts +38 -0
  79. package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts.map +1 -0
  80. package/dist/lib/custom/ai-agent-run/flow/constellation.component.js +200 -0
  81. package/dist/lib/custom/ai-agent-run/flow/constellation.component.js.map +1 -0
  82. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts +44 -0
  83. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts.map +1 -0
  84. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js +180 -0
  85. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js.map +1 -0
  86. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts +12 -0
  87. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts.map +1 -0
  88. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js +46 -0
  89. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js.map +1 -0
  90. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts +64 -0
  91. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts.map +1 -0
  92. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js +267 -0
  93. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js.map +1 -0
  94. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts +53 -0
  95. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts.map +1 -0
  96. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js +111 -0
  97. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js.map +1 -0
  98. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts +42 -0
  99. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts.map +1 -0
  100. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js +193 -0
  101. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js.map +1 -0
  102. package/dist/lib/custom/custom-forms.module.d.ts +58 -51
  103. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  104. package/dist/lib/custom/custom-forms.module.js +52 -13
  105. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  106. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +2 -0
  107. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
  108. package/dist/lib/custom/shared/entity-selector-dialog.component.js +25 -25
  109. package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
  110. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  111. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +280 -216
  112. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  113. package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js +25 -21
  114. package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js.map +1 -1
  115. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.d.ts.map +1 -1
  116. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +68 -14
  117. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
  118. package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.d.ts.map +1 -1
  119. package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js +44 -32
  120. package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js.map +1 -1
  121. package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts +10 -0
  122. package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts.map +1 -0
  123. package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js +66 -0
  124. package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js.map +1 -0
  125. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.d.ts.map +1 -1
  126. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +55 -19
  127. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
  128. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
  129. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +28 -10
  130. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
  131. package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts +10 -0
  132. package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts.map +1 -0
  133. package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js +167 -0
  134. package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js.map +1 -0
  135. package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts +10 -0
  136. package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts.map +1 -0
  137. package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js +64 -0
  138. package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js.map +1 -0
  139. package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts +10 -0
  140. package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts.map +1 -0
  141. package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js +82 -0
  142. package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js.map +1 -0
  143. package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts +10 -0
  144. package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts.map +1 -0
  145. package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js +64 -0
  146. package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js.map +1 -0
  147. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.d.ts.map +1 -1
  148. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js +35 -17
  149. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js.map +1 -1
  150. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.d.ts.map +1 -1
  151. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js +59 -51
  152. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js.map +1 -1
  153. package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.d.ts.map +1 -1
  154. package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js +25 -7
  155. package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js.map +1 -1
  156. package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js +11 -7
  157. package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js.map +1 -1
  158. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.d.ts.map +1 -1
  159. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +56 -46
  160. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
  161. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.d.ts.map +1 -1
  162. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js +73 -59
  163. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js.map +1 -1
  164. package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.d.ts.map +1 -1
  165. package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js +24 -4
  166. package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js.map +1 -1
  167. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  168. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +137 -87
  169. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  170. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.d.ts.map +1 -1
  171. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js +47 -29
  172. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js.map +1 -1
  173. package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts +10 -0
  174. package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts.map +1 -0
  175. package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js +99 -0
  176. package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js.map +1 -0
  177. package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts +10 -0
  178. package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts.map +1 -0
  179. package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js +101 -0
  180. package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js.map +1 -0
  181. package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts +10 -0
  182. package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts.map +1 -0
  183. package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js +115 -0
  184. package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js.map +1 -0
  185. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.d.ts.map +1 -1
  186. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +63 -9
  187. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
  188. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.d.ts.map +1 -1
  189. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js +32 -14
  190. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js.map +1 -1
  191. package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts +10 -0
  192. package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts.map +1 -0
  193. package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js +161 -0
  194. package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js.map +1 -0
  195. package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts +10 -0
  196. package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts.map +1 -0
  197. package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js +89 -0
  198. package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js.map +1 -0
  199. package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts +10 -0
  200. package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts.map +1 -0
  201. package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js +76 -0
  202. package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js.map +1 -0
  203. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts +10 -0
  204. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts.map +1 -0
  205. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js +141 -0
  206. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js.map +1 -0
  207. package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts +10 -0
  208. package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts.map +1 -0
  209. package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js +88 -0
  210. package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js.map +1 -0
  211. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts +10 -0
  212. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts.map +1 -0
  213. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js +143 -0
  214. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js.map +1 -0
  215. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts +10 -0
  216. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts.map +1 -0
  217. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js +110 -0
  218. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js.map +1 -0
  219. package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.d.ts.map +1 -1
  220. package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js +54 -24
  221. package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js.map +1 -1
  222. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.d.ts.map +1 -1
  223. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js +24 -6
  224. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js.map +1 -1
  225. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.d.ts.map +1 -1
  226. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js +36 -18
  227. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js.map +1 -1
  228. package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js +8 -6
  229. package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js.map +1 -1
  230. package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts +10 -0
  231. package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts.map +1 -0
  232. package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js +78 -0
  233. package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js.map +1 -0
  234. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  235. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +145 -109
  236. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  237. package/dist/lib/generated/generated-forms.module.d.ts +356 -335
  238. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  239. package/dist/lib/generated/generated-forms.module.js +304 -226
  240. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  241. package/dist/lib/panels/ai-agents/agent-realtime.panel.js +44 -44
  242. package/dist/lib/panels/ai-agents/agent-realtime.panel.js.map +1 -1
  243. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts +43 -0
  244. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts.map +1 -0
  245. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js +240 -0
  246. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js.map +1 -0
  247. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +69 -0
  248. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -0
  249. package/dist/lib/panels/model-predictions/model-prediction.logic.js +130 -0
  250. package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -0
  251. package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts +83 -0
  252. package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts.map +1 -0
  253. package/dist/lib/panels/model-predictions/model-prediction.panel.js +293 -0
  254. package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -0
  255. package/package.json +38 -37
  256. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts +0 -82
  257. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts.map +0 -1
  258. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js +0 -1033
  259. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js.map +0 -1
@@ -27,17 +27,17 @@ import { BaseFormComponent } from '@memberjunction/ng-base-forms';
27
27
  import { MJSearchScopeProviderFormComponent } from '../../generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component';
28
28
  import * as i0 from "@angular/core";
29
29
  import * as i1 from "@angular/forms";
30
- import * as i2 from "@memberjunction/ng-base-forms";
30
+ import * as i2 from "@memberjunction/ng-ui-components";
31
+ import * as i3 from "@memberjunction/ng-base-forms";
31
32
  const _forTrack0 = ($index, $item) => $item.ID;
32
33
  function MJSearchScopeProviderFormComponentExtended_Conditional_6_Template(rf, ctx) { if (rf & 1) {
33
- i0.ɵɵelementStart(0, "p", 5);
34
- i0.ɵɵelement(1, "i", 20);
35
- i0.ɵɵtext(2);
34
+ i0.ɵɵelementStart(0, "mj-alert", 5);
35
+ i0.ɵɵtext(1);
36
36
  i0.ɵɵelementEnd();
37
37
  } if (rf & 2) {
38
38
  const ctx_r0 = i0.ɵɵnextContext();
39
- i0.ɵɵadvance(2);
40
- i0.ɵɵtextInterpolate1(" Could not load provider catalog \u2014 ", ctx_r0.LoadError, " ");
39
+ i0.ɵɵadvance();
40
+ i0.ɵɵtextInterpolate1("Could not load provider catalog \u2014 ", ctx_r0.LoadError);
41
41
  } }
42
42
  function MJSearchScopeProviderFormComponentExtended_For_11_Template(rf, ctx) { if (rf & 1) {
43
43
  i0.ɵɵelementStart(0, "option", 8);
@@ -50,25 +50,24 @@ function MJSearchScopeProviderFormComponentExtended_For_11_Template(rf, ctx) { i
50
50
  i0.ɵɵtextInterpolate4(" ", option_r2.Name, " \u2014 ", option_r2.DriverClass, "", option_r2.IsRegisteredOnServer ? "" : " (not registered on this server)", "", option_r2.Status !== "Active" ? " [" + option_r2.Status + "]" : "", " ");
51
51
  } }
52
52
  function MJSearchScopeProviderFormComponentExtended_Conditional_12_Template(rf, ctx) { if (rf & 1) {
53
- i0.ɵɵelementStart(0, "p", 9);
54
- i0.ɵɵelement(1, "i", 21);
55
- i0.ɵɵtext(2, " The selected provider's ");
56
- i0.ɵɵelementStart(3, "code");
57
- i0.ɵɵtext(4, "DriverClass");
53
+ i0.ɵɵelementStart(0, "mj-alert", 9);
54
+ i0.ɵɵtext(1, " The selected provider's ");
55
+ i0.ɵɵelementStart(2, "code");
56
+ i0.ɵɵtext(3, "DriverClass");
58
57
  i0.ɵɵelementEnd();
59
- i0.ɵɵtext(5, " is not registered with this MJServer build. Searches using this ");
60
- i0.ɵɵelementStart(6, "code");
61
- i0.ɵɵtext(7, "SearchScopeProvider");
58
+ i0.ɵɵtext(4, " is not registered with this MJServer build. Searches using this ");
59
+ i0.ɵɵelementStart(5, "code");
60
+ i0.ɵɵtext(6, "SearchScopeProvider");
62
61
  i0.ɵɵelementEnd();
63
- i0.ɵɵtext(8, " will return no results until the package that registers ");
64
- i0.ɵɵelementStart(9, "code");
65
- i0.ɵɵtext(10);
62
+ i0.ɵɵtext(7, " will return no results until the package that registers ");
63
+ i0.ɵɵelementStart(8, "code");
64
+ i0.ɵɵtext(9);
66
65
  i0.ɵɵelementEnd();
67
- i0.ɵɵtext(11, " is installed. ");
66
+ i0.ɵɵtext(10, " is installed. ");
68
67
  i0.ɵɵelementEnd();
69
68
  } if (rf & 2) {
70
69
  const ctx_r0 = i0.ɵɵnextContext();
71
- i0.ɵɵadvance(10);
70
+ i0.ɵɵadvance(9);
72
71
  i0.ɵɵtextInterpolate(ctx_r0.SelectedProvider == null ? null : ctx_r0.SelectedProvider.DriverClass);
73
72
  } }
74
73
  let MJSearchScopeProviderFormComponentExtended = class MJSearchScopeProviderFormComponentExtended extends MJSearchScopeProviderFormComponent {
@@ -166,7 +165,7 @@ let MJSearchScopeProviderFormComponentExtended = class MJSearchScopeProviderForm
166
165
  }
167
166
  }
168
167
  static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMJSearchScopeProviderFormComponentExtended_BaseFactory; return function MJSearchScopeProviderFormComponentExtended_Factory(__ngFactoryType__) { return (ɵMJSearchScopeProviderFormComponentExtended_BaseFactory || (ɵMJSearchScopeProviderFormComponentExtended_BaseFactory = i0.ɵɵgetInheritedFactory(MJSearchScopeProviderFormComponentExtended)))(__ngFactoryType__ || MJSearchScopeProviderFormComponentExtended); }; })(); }
169
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJSearchScopeProviderFormComponentExtended, selectors: [["mj-searchscopeprovider-form-extended"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 33, vars: 42, consts: [[3, "Navigate", "DeleteRequested", "FavoriteToggled", "HistoryRequested", "ListManagementRequested", "Record", "FormComponent"], ["SectionKey", "searchConfiguration", "SectionName", "Search Configuration", "Icon", "fa fa-search", 3, "Form", "FormContext"], ["FieldName", "SearchScopeID", "Type", "textbox", "LinkType", "Record", 3, "Record", "ShowLabel", "EditMode", "FormContext"], [1, "provider-picker"], [1, "provider-picker-label"], [1, "provider-picker-error"], [1, "mj-input", "provider-picker-select", 3, "ngModelChange", "disabled", "ngModel"], ["value", ""], [3, "value"], [1, "provider-picker-warning"], [1, "provider-picker-help"], ["SectionKey", "operationalSettings", "SectionName", "Operational Settings", "Icon", "fa fa-sliders-h", 3, "Form", "FormContext"], ["FieldName", "Enabled", "Type", "checkbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "MaxResultsOverride", "Type", "number", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "ProviderConfigOverride", "Type", "code", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "queryProcessing", "SectionName", "Query Processing", "Icon", "fa fa-magic", 3, "Form", "FormContext"], ["FieldName", "QueryTransformTemplateID", "Type", "textbox", "LinkType", "Record", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "systemMetadata", "SectionName", "System Metadata", "Icon", "fa fa-cog", 3, "Form", "FormContext"], ["FieldName", "__mj_CreatedAt", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "__mj_UpdatedAt", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], [1, "fa-solid", "fa-circle-exclamation"], [1, "fa-solid", "fa-triangle-exclamation"]], template: function MJSearchScopeProviderFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
168
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJSearchScopeProviderFormComponentExtended, selectors: [["mj-searchscopeprovider-form-extended"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 33, vars: 42, consts: [[3, "Navigate", "DeleteRequested", "FavoriteToggled", "HistoryRequested", "ListManagementRequested", "Record", "FormComponent"], ["SectionKey", "searchConfiguration", "SectionName", "Search Configuration", "Icon", "fa fa-search", 3, "Form", "FormContext"], ["FieldName", "SearchScopeID", "Type", "textbox", "LinkType", "Record", 3, "Record", "ShowLabel", "EditMode", "FormContext"], [1, "provider-picker"], [1, "provider-picker-label"], ["Variant", "error"], [1, "mj-input", "provider-picker-select", 3, "ngModelChange", "disabled", "ngModel"], ["value", ""], [3, "value"], ["Variant", "warning"], [1, "provider-picker-help"], ["SectionKey", "operationalSettings", "SectionName", "Operational Settings", "Icon", "fa fa-sliders-h", 3, "Form", "FormContext"], ["FieldName", "Enabled", "Type", "checkbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "MaxResultsOverride", "Type", "number", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "ProviderConfigOverride", "Type", "code", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "queryProcessing", "SectionName", "Query Processing", "Icon", "fa fa-magic", 3, "Form", "FormContext"], ["FieldName", "QueryTransformTemplateID", "Type", "textbox", "LinkType", "Record", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "systemMetadata", "SectionName", "System Metadata", "Icon", "fa fa-cog", 3, "Form", "FormContext"], ["FieldName", "__mj_CreatedAt", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "__mj_UpdatedAt", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"]], template: function MJSearchScopeProviderFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
170
169
  i0.ɵɵelementStart(0, "mj-record-form-container", 0);
171
170
  i0.ɵɵlistener("Navigate", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_Navigate_0_listener($event) { return ctx.OnFormNavigate($event); })("DeleteRequested", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_DeleteRequested_0_listener() { return ctx.OnDeleteRequested(); })("FavoriteToggled", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_FavoriteToggled_0_listener() { return ctx.OnFavoriteToggled(); })("HistoryRequested", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_HistoryRequested_0_listener() { return ctx.OnHistoryRequested(); })("ListManagementRequested", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_ListManagementRequested_0_listener() { return ctx.OnListManagementRequested(); });
172
171
  i0.ɵɵelementStart(1, "mj-collapsible-panel", 1);
@@ -174,7 +173,7 @@ let MJSearchScopeProviderFormComponentExtended = class MJSearchScopeProviderForm
174
173
  i0.ɵɵelementStart(3, "div", 3)(4, "label", 4);
175
174
  i0.ɵɵtext(5, "Search Provider");
176
175
  i0.ɵɵelementEnd();
177
- i0.ɵɵconditionalCreate(6, MJSearchScopeProviderFormComponentExtended_Conditional_6_Template, 3, 1, "p", 5);
176
+ i0.ɵɵconditionalCreate(6, MJSearchScopeProviderFormComponentExtended_Conditional_6_Template, 2, 1, "mj-alert", 5);
178
177
  i0.ɵɵelementStart(7, "select", 6);
179
178
  i0.ɵɵlistener("ngModelChange", function MJSearchScopeProviderFormComponentExtended_Template_select_ngModelChange_7_listener($event) { return ctx.SelectedSearchProviderID = $event; });
180
179
  i0.ɵɵelementStart(8, "option", 7);
@@ -182,7 +181,7 @@ let MJSearchScopeProviderFormComponentExtended = class MJSearchScopeProviderForm
182
181
  i0.ɵɵelementEnd();
183
182
  i0.ɵɵrepeaterCreate(10, MJSearchScopeProviderFormComponentExtended_For_11_Template, 2, 5, "option", 8, _forTrack0);
184
183
  i0.ɵɵelementEnd();
185
- i0.ɵɵconditionalCreate(12, MJSearchScopeProviderFormComponentExtended_Conditional_12_Template, 12, 1, "p", 9);
184
+ i0.ɵɵconditionalCreate(12, MJSearchScopeProviderFormComponentExtended_Conditional_12_Template, 11, 1, "mj-alert", 9);
186
185
  i0.ɵɵelementStart(13, "p", 10);
187
186
  i0.ɵɵtext(14, " Picks from rows in ");
188
187
  i0.ɵɵelementStart(15, "code");
@@ -239,7 +238,7 @@ let MJSearchScopeProviderFormComponentExtended = class MJSearchScopeProviderForm
239
238
  i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
240
239
  i0.ɵɵadvance();
241
240
  i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
242
- } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MjFormFieldComponent, i2.MjCollapsiblePanelComponent, i2.MjRecordFormContainerComponent], styles: [".provider-picker[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-top: 0.5rem;\n}\n\n.provider-picker-label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-picker-select[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 600px;\n}\n\n.provider-picker-error[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-status-error-text);\n background: var(--mj-status-error-bg);\n padding: 0.5rem 0.75rem;\n border-left: 3px solid var(--mj-status-error-border);\n border-radius: 2px;\n}\n\n.provider-picker-warning[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-status-warning-text);\n background: var(--mj-status-warning-bg);\n padding: 0.5rem 0.75rem;\n border-left: 3px solid var(--mj-status-warning-border);\n border-radius: 2px;\n}\n\n.provider-picker-warning[_ngcontent-%COMP%] code[_ngcontent-%COMP%], \n.provider-picker-help[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 2px;\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 0.85em;\n}\n\n.provider-picker-help[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--mj-text-muted);\n}"] }); }
241
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJAlertComponent, i3.MjFormFieldComponent, i3.MjCollapsiblePanelComponent, i3.MjRecordFormContainerComponent], styles: [".provider-picker[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-top: 0.5rem;\n}\n\n.provider-picker-label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-picker-select[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 600px;\n}\n\n.provider-picker-help[_ngcontent-%COMP%] code[_ngcontent-%COMP%], \nmj-alert[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 2px;\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 0.85em;\n}\n\n.provider-picker-help[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--mj-text-muted);\n}"] }); }
243
242
  };
244
243
  MJSearchScopeProviderFormComponentExtended = __decorate([
245
244
  RegisterClass(BaseFormComponent, 'MJ: Search Scope Providers')
@@ -247,7 +246,7 @@ MJSearchScopeProviderFormComponentExtended = __decorate([
247
246
  export { MJSearchScopeProviderFormComponentExtended };
248
247
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJSearchScopeProviderFormComponentExtended, [{
249
248
  type: Component,
250
- args: [{ standalone: false, selector: 'mj-searchscopeprovider-form-extended', template: "<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n\n <!-- ========================================\n FIELD PANELS\n ======================================== -->\n <!-- Search Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"searchConfiguration\"\n SectionName=\"Search Configuration\"\n Icon=\"fa fa-search\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"SearchScopeID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n <!-- P5.5 \u2014 provider picker. Replaces the generated form's plain\n SearchProviderID textbox. Sourced from MJ: Search Providers\n rows; each option is annotated with whether the provider's\n DriverClass is currently registered with the server's\n ClassFactory. -->\n <div class=\"provider-picker\">\n <label class=\"provider-picker-label\">Search Provider</label>\n @if (LoadError) {\n <p class=\"provider-picker-error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n Could not load provider catalog \u2014 {{ LoadError }}\n </p>\n }\n <select\n class=\"mj-input provider-picker-select\"\n [disabled]=\"!EditMode || !ProvidersLoaded\"\n [ngModel]=\"SelectedSearchProviderID\"\n (ngModelChange)=\"SelectedSearchProviderID = $event\">\n <option value=\"\">\u2014 Select a provider \u2014</option>\n @for (option of AvailableProviders; track option.ID) {\n <option [value]=\"option.ID\">\n {{ option.Name }} \u2014 {{ option.DriverClass }}{{ option.IsRegisteredOnServer ? '' : ' (not registered on this server)' }}{{ option.Status !== 'Active' ? ' [' + option.Status + ']' : '' }}\n </option>\n }\n </select>\n @if (SelectedProviderUnregisteredOnServer) {\n <p class=\"provider-picker-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n The selected provider's <code>DriverClass</code> is not registered with this MJServer build.\n Searches using this <code>SearchScopeProvider</code> will return no results until the\n package that registers <code>{{ SelectedProvider?.DriverClass }}</code> is installed.\n </p>\n }\n <p class=\"provider-picker-help\">\n Picks from rows in <code>MJ: Search Providers</code>. The \"(not registered on this server)\" suffix\n comes from the <code>AvailableSearchProviders</code> query, which calls\n <code>BaseSearchProvider.GetAvailableProviders()</code> server-side to enumerate\n ClassFactory registrations.\n </p>\n </div>\n\n </mj-collapsible-panel>\n\n <!-- Operational Settings Section -->\n <mj-collapsible-panel\n SectionKey=\"operationalSettings\"\n SectionName=\"Operational Settings\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Enabled\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"MaxResultsOverride\"\n Type=\"number\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ProviderConfigOverride\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Query Processing Section -->\n <mj-collapsible-panel\n SectionKey=\"queryProcessing\"\n SectionName=\"Query Processing\"\n Icon=\"fa fa-magic\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"false\"\n FieldName=\"QueryTransformTemplateID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- System Metadata Section -->\n <mj-collapsible-panel\n SectionKey=\"systemMetadata\"\n SectionName=\"System Metadata\"\n Icon=\"fa fa-cog\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_CreatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_UpdatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n</mj-record-form-container>\n", styles: [".provider-picker {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-top: 0.5rem;\n}\n\n.provider-picker-label {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-picker-select {\n width: 100%;\n max-width: 600px;\n}\n\n.provider-picker-error {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-status-error-text);\n background: var(--mj-status-error-bg);\n padding: 0.5rem 0.75rem;\n border-left: 3px solid var(--mj-status-error-border);\n border-radius: 2px;\n}\n\n.provider-picker-warning {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-status-warning-text);\n background: var(--mj-status-warning-bg);\n padding: 0.5rem 0.75rem;\n border-left: 3px solid var(--mj-status-warning-border);\n border-radius: 2px;\n}\n\n.provider-picker-warning code,\n.provider-picker-help code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 2px;\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 0.85em;\n}\n\n.provider-picker-help {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--mj-text-muted);\n}\n"] }]
249
+ args: [{ standalone: false, selector: 'mj-searchscopeprovider-form-extended', template: "<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n\n <!-- ========================================\n FIELD PANELS\n ======================================== -->\n <!-- Search Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"searchConfiguration\"\n SectionName=\"Search Configuration\"\n Icon=\"fa fa-search\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"SearchScopeID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n <!-- P5.5 \u2014 provider picker. Replaces the generated form's plain\n SearchProviderID textbox. Sourced from MJ: Search Providers\n rows; each option is annotated with whether the provider's\n DriverClass is currently registered with the server's\n ClassFactory. -->\n <div class=\"provider-picker\">\n <label class=\"provider-picker-label\">Search Provider</label>\n @if (LoadError) {\n <mj-alert Variant=\"error\">Could not load provider catalog \u2014 {{ LoadError }}</mj-alert>\n }\n <select\n class=\"mj-input provider-picker-select\"\n [disabled]=\"!EditMode || !ProvidersLoaded\"\n [ngModel]=\"SelectedSearchProviderID\"\n (ngModelChange)=\"SelectedSearchProviderID = $event\">\n <option value=\"\">\u2014 Select a provider \u2014</option>\n @for (option of AvailableProviders; track option.ID) {\n <option [value]=\"option.ID\">\n {{ option.Name }} \u2014 {{ option.DriverClass }}{{ option.IsRegisteredOnServer ? '' : ' (not registered on this server)' }}{{ option.Status !== 'Active' ? ' [' + option.Status + ']' : '' }}\n </option>\n }\n </select>\n @if (SelectedProviderUnregisteredOnServer) {\n <mj-alert Variant=\"warning\">\n The selected provider's <code>DriverClass</code> is not registered with this MJServer build.\n Searches using this <code>SearchScopeProvider</code> will return no results until the\n package that registers <code>{{ SelectedProvider?.DriverClass }}</code> is installed.\n </mj-alert>\n }\n <p class=\"provider-picker-help\">\n Picks from rows in <code>MJ: Search Providers</code>. The \"(not registered on this server)\" suffix\n comes from the <code>AvailableSearchProviders</code> query, which calls\n <code>BaseSearchProvider.GetAvailableProviders()</code> server-side to enumerate\n ClassFactory registrations.\n </p>\n </div>\n\n </mj-collapsible-panel>\n\n <!-- Operational Settings Section -->\n <mj-collapsible-panel\n SectionKey=\"operationalSettings\"\n SectionName=\"Operational Settings\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Enabled\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"MaxResultsOverride\"\n Type=\"number\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ProviderConfigOverride\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Query Processing Section -->\n <mj-collapsible-panel\n SectionKey=\"queryProcessing\"\n SectionName=\"Query Processing\"\n Icon=\"fa fa-magic\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"false\"\n FieldName=\"QueryTransformTemplateID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- System Metadata Section -->\n <mj-collapsible-panel\n SectionKey=\"systemMetadata\"\n SectionName=\"System Metadata\"\n Icon=\"fa fa-cog\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_CreatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_UpdatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n</mj-record-form-container>\n", styles: [".provider-picker {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-top: 0.5rem;\n}\n\n.provider-picker-label {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-picker-select {\n width: 100%;\n max-width: 600px;\n}\n\n.provider-picker-help code,\nmj-alert code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 2px;\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 0.85em;\n}\n\n.provider-picker-help {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--mj-text-muted);\n}\n"] }]
251
250
  }], null, null); })();
252
251
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJSearchScopeProviderFormComponentExtended, { className: "MJSearchScopeProviderFormComponentExtended", filePath: "src/lib/custom/SearchScopes/searchscopeprovider-form.component.ts", lineNumber: 46 }); })();
253
252
  //# sourceMappingURL=searchscopeprovider-form.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"searchscopeprovider-form.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/SearchScopes/searchscopeprovider-form.component.ts","../../../../src/lib/custom/SearchScopes/searchscopeprovider-form.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * Custom MJSearchScopeProvider form (P5.5).\n *\n * Plan acceptance criterion: provide a dropdown for `SearchProviderID` so\n * scope authors don't have to look up GUIDs by hand. The dropdown is sourced\n * from the `MJ: Search Providers` table (those rows are the canonical FK\n * targets), and each option is annotated with whether the provider's\n * `DriverClass` is currently registered with the runtime ClassFactory on\n * this MJServer build — so authors can see at a glance whether their pick\n * will actually be available at search time.\n *\n * The runtime registration list comes from the `AvailableSearchProviders`\n * GraphQL query backed by `BaseSearchProvider.GetAvailableProviders()`.\n * That query is the canonical \"which providers does this server know\n * about\" source — same helper Phase 5.5 of the RAG plan calls out.\n */\nimport { Component, OnInit } from '@angular/core';\nimport { LogError, Metadata, RunView } from '@memberjunction/core';\nimport { MJSearchScopeProviderEntity, MJSearchProviderEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseFormComponent } from '@memberjunction/ng-base-forms';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { MJSearchScopeProviderFormComponent } from '../../generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component';\n\ninterface SearchProviderOption {\n ID: string;\n Name: string;\n DriverClass: string;\n Status: 'Active' | 'Pending' | 'Terminated';\n /**\n * `true` if `DriverClass` matches a class currently registered with the\n * runtime ClassFactory on this MJServer. `false` means the row exists in\n * `MJ: Search Providers` but no installed package registers that class —\n * picking it would result in `IsAvailable()=false` at search time.\n */\n IsRegisteredOnServer: boolean;\n}\n\n@RegisterClass(BaseFormComponent, 'MJ: Search Scope Providers')\n@Component({\n standalone: false,\n selector: 'mj-searchscopeprovider-form-extended',\n templateUrl: './searchscopeprovider-form.component.html',\n styleUrls: ['./searchscopeprovider-form.component.css'],\n})\nexport class MJSearchScopeProviderFormComponentExtended extends MJSearchScopeProviderFormComponent implements OnInit {\n public override record!: MJSearchScopeProviderEntity;\n\n public AvailableProviders: SearchProviderOption[] = [];\n public ProvidersLoaded = false;\n public LoadError: string | null = null;\n\n /**\n * Drives the dropdown's `[ngModel]`. Kept in sync with `record.SearchProviderID`\n * via the setter so dirty tracking and the form's save flow continue to work.\n */\n public get SelectedSearchProviderID(): string {\n return this.record?.SearchProviderID ?? '';\n }\n public set SelectedSearchProviderID(value: string) {\n if (!this.record) return;\n if (this.record.SearchProviderID === value) return;\n this.record.SearchProviderID = value;\n }\n\n public get SelectedProvider(): SearchProviderOption | null {\n const id = this.SelectedSearchProviderID;\n if (!id) return null;\n return this.AvailableProviders.find(p => p.ID.toLowerCase() === id.toLowerCase()) ?? null;\n }\n\n public get SelectedProviderUnregisteredOnServer(): boolean {\n const sel = this.SelectedProvider;\n return sel != null && !sel.IsRegisteredOnServer;\n }\n\n override async ngOnInit(): Promise<void> {\n await super.ngOnInit();\n await this.loadProviderCatalog();\n }\n\n /**\n * Pulls the `MJ: Search Providers` rows and the server-registered class list\n * in parallel, then merges into one dropdown source. Failures don't block the\n * form — the dropdown just disables itself, leaving the underlying generated\n * textbox accessible via `EditMode`.\n */\n private async loadProviderCatalog(): Promise<void> {\n try {\n const rv = new RunView();\n const [rowsResult, registeredKeys] = await Promise.all([\n rv.RunView<MJSearchProviderEntity>({\n EntityName: 'MJ: Search Providers',\n OrderBy: 'Name',\n ResultType: 'simple',\n }),\n this.fetchRegisteredDriverClasses(),\n ]);\n\n if (!rowsResult.Success) {\n this.LoadError = rowsResult.ErrorMessage ?? 'Unknown error loading providers';\n LogError(`MJSearchScopeProviderFormExtended: RunView failed: ${this.LoadError}`);\n return;\n }\n\n const registeredSet = new Set(registeredKeys.map(k => k.toLowerCase()));\n const rows = rowsResult.Results ?? [];\n this.AvailableProviders = rows.map(row => ({\n ID: row.ID,\n Name: row.Name,\n DriverClass: row.DriverClass,\n Status: row.Status,\n IsRegisteredOnServer: registeredSet.has(row.DriverClass.toLowerCase()),\n }));\n this.ProvidersLoaded = true;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.LoadError = msg;\n LogError(`MJSearchScopeProviderFormExtended: catalog load threw: ${msg}`);\n }\n }\n\n /**\n * Calls the `AvailableSearchProviders` GraphQL query to learn which\n * `DriverClass` keys are actually registered with `MJGlobal.ClassFactory`\n * on the server. Returns `[]` on any failure — the dropdown still renders\n * from the DB rows; we just lose the \"(not registered)\" badge.\n */\n private async fetchRegisteredDriverClasses(): Promise<string[]> {\n try {\n const dataProvider = this.ProviderToUse as GraphQLDataProvider;\n const response = await dataProvider.ExecuteGQL(\n `query AvailableSearchProviders { AvailableSearchProviders { DriverClass SourceType } }`,\n {}\n ) as { AvailableSearchProviders?: Array<{ DriverClass: string }> };\n return (response?.AvailableSearchProviders ?? []).map(r => r.DriverClass);\n } catch (err) {\n // Older server build won't have the resolver. The dropdown still\n // works from DB rows; the registration badge just won't appear.\n const msg = err instanceof Error ? err.message : String(err);\n LogError(`MJSearchScopeProviderFormExtended: AvailableSearchProviders query failed (badge disabled): ${msg}`);\n return [];\n }\n }\n}\n","<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n\n <!-- ========================================\n FIELD PANELS\n ======================================== -->\n <!-- Search Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"searchConfiguration\"\n SectionName=\"Search Configuration\"\n Icon=\"fa fa-search\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"SearchScopeID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n <!-- P5.5 — provider picker. Replaces the generated form's plain\n SearchProviderID textbox. Sourced from MJ: Search Providers\n rows; each option is annotated with whether the provider's\n DriverClass is currently registered with the server's\n ClassFactory. -->\n <div class=\"provider-picker\">\n <label class=\"provider-picker-label\">Search Provider</label>\n @if (LoadError) {\n <p class=\"provider-picker-error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n Could not load provider catalog — {{ LoadError }}\n </p>\n }\n <select\n class=\"mj-input provider-picker-select\"\n [disabled]=\"!EditMode || !ProvidersLoaded\"\n [ngModel]=\"SelectedSearchProviderID\"\n (ngModelChange)=\"SelectedSearchProviderID = $event\">\n <option value=\"\">— Select a provider —</option>\n @for (option of AvailableProviders; track option.ID) {\n <option [value]=\"option.ID\">\n {{ option.Name }} — {{ option.DriverClass }}{{ option.IsRegisteredOnServer ? '' : ' (not registered on this server)' }}{{ option.Status !== 'Active' ? ' [' + option.Status + ']' : '' }}\n </option>\n }\n </select>\n @if (SelectedProviderUnregisteredOnServer) {\n <p class=\"provider-picker-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n The selected provider's <code>DriverClass</code> is not registered with this MJServer build.\n Searches using this <code>SearchScopeProvider</code> will return no results until the\n package that registers <code>{{ SelectedProvider?.DriverClass }}</code> is installed.\n </p>\n }\n <p class=\"provider-picker-help\">\n Picks from rows in <code>MJ: Search Providers</code>. The \"(not registered on this server)\" suffix\n comes from the <code>AvailableSearchProviders</code> query, which calls\n <code>BaseSearchProvider.GetAvailableProviders()</code> server-side to enumerate\n ClassFactory registrations.\n </p>\n </div>\n\n </mj-collapsible-panel>\n\n <!-- Operational Settings Section -->\n <mj-collapsible-panel\n SectionKey=\"operationalSettings\"\n SectionName=\"Operational Settings\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Enabled\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"MaxResultsOverride\"\n Type=\"number\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ProviderConfigOverride\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Query Processing Section -->\n <mj-collapsible-panel\n SectionKey=\"queryProcessing\"\n SectionName=\"Query Processing\"\n Icon=\"fa fa-magic\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"false\"\n FieldName=\"QueryTransformTemplateID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- System Metadata Section -->\n <mj-collapsible-panel\n SectionKey=\"systemMetadata\"\n SectionName=\"System Metadata\"\n Icon=\"fa fa-cog\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_CreatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_UpdatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n</mj-record-form-container>\n"]}
1
+ {"version":3,"file":"searchscopeprovider-form.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/SearchScopes/searchscopeprovider-form.component.ts","../../../../src/lib/custom/SearchScopes/searchscopeprovider-form.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * Custom MJSearchScopeProvider form (P5.5).\n *\n * Plan acceptance criterion: provide a dropdown for `SearchProviderID` so\n * scope authors don't have to look up GUIDs by hand. The dropdown is sourced\n * from the `MJ: Search Providers` table (those rows are the canonical FK\n * targets), and each option is annotated with whether the provider's\n * `DriverClass` is currently registered with the runtime ClassFactory on\n * this MJServer build — so authors can see at a glance whether their pick\n * will actually be available at search time.\n *\n * The runtime registration list comes from the `AvailableSearchProviders`\n * GraphQL query backed by `BaseSearchProvider.GetAvailableProviders()`.\n * That query is the canonical \"which providers does this server know\n * about\" source — same helper Phase 5.5 of the RAG plan calls out.\n */\nimport { Component, OnInit } from '@angular/core';\nimport { LogError, Metadata, RunView } from '@memberjunction/core';\nimport { MJSearchScopeProviderEntity, MJSearchProviderEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseFormComponent } from '@memberjunction/ng-base-forms';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { MJSearchScopeProviderFormComponent } from '../../generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component';\n\ninterface SearchProviderOption {\n ID: string;\n Name: string;\n DriverClass: string;\n Status: 'Active' | 'Pending' | 'Terminated';\n /**\n * `true` if `DriverClass` matches a class currently registered with the\n * runtime ClassFactory on this MJServer. `false` means the row exists in\n * `MJ: Search Providers` but no installed package registers that class —\n * picking it would result in `IsAvailable()=false` at search time.\n */\n IsRegisteredOnServer: boolean;\n}\n\n@RegisterClass(BaseFormComponent, 'MJ: Search Scope Providers')\n@Component({\n standalone: false,\n selector: 'mj-searchscopeprovider-form-extended',\n templateUrl: './searchscopeprovider-form.component.html',\n styleUrls: ['./searchscopeprovider-form.component.css'],\n})\nexport class MJSearchScopeProviderFormComponentExtended extends MJSearchScopeProviderFormComponent implements OnInit {\n public override record!: MJSearchScopeProviderEntity;\n\n public AvailableProviders: SearchProviderOption[] = [];\n public ProvidersLoaded = false;\n public LoadError: string | null = null;\n\n /**\n * Drives the dropdown's `[ngModel]`. Kept in sync with `record.SearchProviderID`\n * via the setter so dirty tracking and the form's save flow continue to work.\n */\n public get SelectedSearchProviderID(): string {\n return this.record?.SearchProviderID ?? '';\n }\n public set SelectedSearchProviderID(value: string) {\n if (!this.record) return;\n if (this.record.SearchProviderID === value) return;\n this.record.SearchProviderID = value;\n }\n\n public get SelectedProvider(): SearchProviderOption | null {\n const id = this.SelectedSearchProviderID;\n if (!id) return null;\n return this.AvailableProviders.find(p => p.ID.toLowerCase() === id.toLowerCase()) ?? null;\n }\n\n public get SelectedProviderUnregisteredOnServer(): boolean {\n const sel = this.SelectedProvider;\n return sel != null && !sel.IsRegisteredOnServer;\n }\n\n override async ngOnInit(): Promise<void> {\n await super.ngOnInit();\n await this.loadProviderCatalog();\n }\n\n /**\n * Pulls the `MJ: Search Providers` rows and the server-registered class list\n * in parallel, then merges into one dropdown source. Failures don't block the\n * form — the dropdown just disables itself, leaving the underlying generated\n * textbox accessible via `EditMode`.\n */\n private async loadProviderCatalog(): Promise<void> {\n try {\n const rv = new RunView();\n const [rowsResult, registeredKeys] = await Promise.all([\n rv.RunView<MJSearchProviderEntity>({\n EntityName: 'MJ: Search Providers',\n OrderBy: 'Name',\n ResultType: 'simple',\n }),\n this.fetchRegisteredDriverClasses(),\n ]);\n\n if (!rowsResult.Success) {\n this.LoadError = rowsResult.ErrorMessage ?? 'Unknown error loading providers';\n LogError(`MJSearchScopeProviderFormExtended: RunView failed: ${this.LoadError}`);\n return;\n }\n\n const registeredSet = new Set(registeredKeys.map(k => k.toLowerCase()));\n const rows = rowsResult.Results ?? [];\n this.AvailableProviders = rows.map(row => ({\n ID: row.ID,\n Name: row.Name,\n DriverClass: row.DriverClass,\n Status: row.Status,\n IsRegisteredOnServer: registeredSet.has(row.DriverClass.toLowerCase()),\n }));\n this.ProvidersLoaded = true;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.LoadError = msg;\n LogError(`MJSearchScopeProviderFormExtended: catalog load threw: ${msg}`);\n }\n }\n\n /**\n * Calls the `AvailableSearchProviders` GraphQL query to learn which\n * `DriverClass` keys are actually registered with `MJGlobal.ClassFactory`\n * on the server. Returns `[]` on any failure — the dropdown still renders\n * from the DB rows; we just lose the \"(not registered)\" badge.\n */\n private async fetchRegisteredDriverClasses(): Promise<string[]> {\n try {\n const dataProvider = this.ProviderToUse as GraphQLDataProvider;\n const response = await dataProvider.ExecuteGQL(\n `query AvailableSearchProviders { AvailableSearchProviders { DriverClass SourceType } }`,\n {}\n ) as { AvailableSearchProviders?: Array<{ DriverClass: string }> };\n return (response?.AvailableSearchProviders ?? []).map(r => r.DriverClass);\n } catch (err) {\n // Older server build won't have the resolver. The dropdown still\n // works from DB rows; the registration badge just won't appear.\n const msg = err instanceof Error ? err.message : String(err);\n LogError(`MJSearchScopeProviderFormExtended: AvailableSearchProviders query failed (badge disabled): ${msg}`);\n return [];\n }\n }\n}\n","<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n\n <!-- ========================================\n FIELD PANELS\n ======================================== -->\n <!-- Search Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"searchConfiguration\"\n SectionName=\"Search Configuration\"\n Icon=\"fa fa-search\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"SearchScopeID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n <!-- P5.5 — provider picker. Replaces the generated form's plain\n SearchProviderID textbox. Sourced from MJ: Search Providers\n rows; each option is annotated with whether the provider's\n DriverClass is currently registered with the server's\n ClassFactory. -->\n <div class=\"provider-picker\">\n <label class=\"provider-picker-label\">Search Provider</label>\n @if (LoadError) {\n <mj-alert Variant=\"error\">Could not load provider catalog — {{ LoadError }}</mj-alert>\n }\n <select\n class=\"mj-input provider-picker-select\"\n [disabled]=\"!EditMode || !ProvidersLoaded\"\n [ngModel]=\"SelectedSearchProviderID\"\n (ngModelChange)=\"SelectedSearchProviderID = $event\">\n <option value=\"\">— Select a provider —</option>\n @for (option of AvailableProviders; track option.ID) {\n <option [value]=\"option.ID\">\n {{ option.Name }} — {{ option.DriverClass }}{{ option.IsRegisteredOnServer ? '' : ' (not registered on this server)' }}{{ option.Status !== 'Active' ? ' [' + option.Status + ']' : '' }}\n </option>\n }\n </select>\n @if (SelectedProviderUnregisteredOnServer) {\n <mj-alert Variant=\"warning\">\n The selected provider's <code>DriverClass</code> is not registered with this MJServer build.\n Searches using this <code>SearchScopeProvider</code> will return no results until the\n package that registers <code>{{ SelectedProvider?.DriverClass }}</code> is installed.\n </mj-alert>\n }\n <p class=\"provider-picker-help\">\n Picks from rows in <code>MJ: Search Providers</code>. The \"(not registered on this server)\" suffix\n comes from the <code>AvailableSearchProviders</code> query, which calls\n <code>BaseSearchProvider.GetAvailableProviders()</code> server-side to enumerate\n ClassFactory registrations.\n </p>\n </div>\n\n </mj-collapsible-panel>\n\n <!-- Operational Settings Section -->\n <mj-collapsible-panel\n SectionKey=\"operationalSettings\"\n SectionName=\"Operational Settings\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Enabled\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"MaxResultsOverride\"\n Type=\"number\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ProviderConfigOverride\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Query Processing Section -->\n <mj-collapsible-panel\n SectionKey=\"queryProcessing\"\n SectionName=\"Query Processing\"\n Icon=\"fa fa-magic\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"false\"\n FieldName=\"QueryTransformTemplateID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- System Metadata Section -->\n <mj-collapsible-panel\n SectionKey=\"systemMetadata\"\n SectionName=\"System Metadata\"\n Icon=\"fa fa-cog\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_CreatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_UpdatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n</mj-record-form-container>\n"]}
@@ -155,19 +155,14 @@ function TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_6
155
155
  } }
156
156
  function TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_7_Template(rf, ctx) { if (rf & 1) {
157
157
  const _r10 = i0.ɵɵgetCurrentView();
158
- i0.ɵɵelementStart(0, "div", 21);
159
- i0.ɵɵelement(1, "i", 19);
160
- i0.ɵɵelementStart(2, "p");
161
- i0.ɵɵtext(3, "No parameters defined yet");
162
- i0.ɵɵelementEnd();
163
- i0.ɵɵelementStart(4, "button", 51);
164
- i0.ɵɵlistener("click", function TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_7_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.addParameter()); });
165
- i0.ɵɵelement(5, "i", 34);
166
- i0.ɵɵtext(6, " Add First Parameter ");
158
+ i0.ɵɵelementStart(0, "mj-empty-state", 21)(1, "button", 51);
159
+ i0.ɵɵlistener("click", function TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_7_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.addParameter()); });
160
+ i0.ɵɵelement(2, "i", 34);
161
+ i0.ɵɵtext(3, " Add First Parameter ");
167
162
  i0.ɵɵelementEnd()();
168
163
  } if (rf & 2) {
169
164
  const ctx_r1 = i0.ɵɵnextContext(3);
170
- i0.ɵɵadvance(4);
165
+ i0.ɵɵadvance();
171
166
  i0.ɵɵproperty("disabled", ctx_r1.isRunning);
172
167
  } }
173
168
  function TemplateParamDialogComponent_Conditional_0_Conditional_15_ng_template_9_Template(rf, ctx) { if (rf & 1) {
@@ -281,11 +276,7 @@ function TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_1
281
276
  i0.ɵɵconditional(ctx_r1.testResult.success && ctx_r1.testResult.output ? 14 : !ctx_r1.testResult.success && ctx_r1.testResult.error ? 15 : -1);
282
277
  } }
283
278
  function TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_19_Template(rf, ctx) { if (rf & 1) {
284
- i0.ɵɵelementStart(0, "div", 27)(1, "div", 69);
285
- i0.ɵɵelement(2, "i", 70);
286
- i0.ɵɵelementStart(3, "p");
287
- i0.ɵɵtext(4, "No test results yet. Run the template to see results here.");
288
- i0.ɵɵelementEnd()()();
279
+ i0.ɵɵelement(0, "mj-empty-state", 27);
289
280
  } }
290
281
  function TemplateParamDialogComponent_Conditional_0_Conditional_15_Template(rf, ctx) { if (rf & 1) {
291
282
  const _r3 = i0.ɵɵgetCurrentView();
@@ -296,7 +287,7 @@ function TemplateParamDialogComponent_Conditional_0_Conditional_15_Template(rf,
296
287
  i0.ɵɵelement(4, "i", 19);
297
288
  i0.ɵɵtext(5, " Configure parameter values for template testing. Values can be JSON objects, strings, or numbers. ");
298
289
  i0.ɵɵelementEnd();
299
- i0.ɵɵconditionalCreate(6, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_6_Template, 14, 1, "div", 20)(7, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_7_Template, 7, 1, "div", 21);
290
+ i0.ɵɵconditionalCreate(6, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_6_Template, 14, 1, "div", 20)(7, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_7_Template, 4, 1, "mj-empty-state", 21);
300
291
  i0.ɵɵelementEnd()();
301
292
  i0.ɵɵelementStart(8, "mj-accordion-panel", 15);
302
293
  i0.ɵɵtwoWayListener("ExpandedChange", function TemplateParamDialogComponent_Conditional_0_Conditional_15_Template_mj_accordion_panel_ExpandedChange_8_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.jsonPreviewExpanded, $event) || (ctx_r1.jsonPreviewExpanded = $event); return i0.ɵɵresetView($event); });
@@ -308,7 +299,7 @@ function TemplateParamDialogComponent_Conditional_0_Conditional_15_Template(rf,
308
299
  i0.ɵɵtwoWayListener("ExpandedChange", function TemplateParamDialogComponent_Conditional_0_Conditional_15_Template_mj_accordion_panel_ExpandedChange_14_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.resultsExpanded, $event) || (ctx_r1.resultsExpanded = $event); return i0.ɵɵresetView($event); });
309
300
  i0.ɵɵtemplate(15, TemplateParamDialogComponent_Conditional_0_Conditional_15_ng_template_15_Template, 4, 1, "ng-template", 16);
310
301
  i0.ɵɵelementStart(16, "div", 24);
311
- i0.ɵɵconditionalCreate(17, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_17_Template, 4, 0, "div", 25)(18, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_18_Template, 16, 7, "div", 26)(19, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_19_Template, 5, 0, "div", 27);
302
+ i0.ɵɵconditionalCreate(17, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_17_Template, 4, 0, "div", 25)(18, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_18_Template, 16, 7, "div", 26)(19, TemplateParamDialogComponent_Conditional_0_Conditional_15_Conditional_19_Template, 1, 0, "mj-empty-state", 27);
312
303
  i0.ɵɵelementEnd()();
313
304
  } if (rf & 2) {
314
305
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -326,9 +317,9 @@ function TemplateParamDialogComponent_Conditional_0_Conditional_15_Template(rf,
326
317
  } }
327
318
  function TemplateParamDialogComponent_Conditional_0_Conditional_19_Template(rf, ctx) { if (rf & 1) {
328
319
  const _r12 = i0.ɵɵgetCurrentView();
329
- i0.ɵɵelementStart(0, "button", 71);
320
+ i0.ɵɵelementStart(0, "button", 69);
330
321
  i0.ɵɵlistener("click", function TemplateParamDialogComponent_Conditional_0_Conditional_19_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateTemplateParams()); });
331
- i0.ɵɵelement(1, "i", 72);
322
+ i0.ɵɵelement(1, "i", 70);
332
323
  i0.ɵɵtext(2, " Update Template Params ");
333
324
  i0.ɵɵelementEnd();
334
325
  } if (rf & 2) {
@@ -348,7 +339,7 @@ function TemplateParamDialogComponent_Conditional_0_Conditional_25_Template(rf,
348
339
  i0.ɵɵtext(1, " Running... ");
349
340
  } }
350
341
  function TemplateParamDialogComponent_Conditional_0_Conditional_26_Template(rf, ctx) { if (rf & 1) {
351
- i0.ɵɵelement(0, "i", 73);
342
+ i0.ɵɵelement(0, "i", 71);
352
343
  i0.ɵɵtext(1, " Run Template ");
353
344
  } }
354
345
  function TemplateParamDialogComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
@@ -638,15 +629,15 @@ export class TemplateParamDialogComponent extends BaseAngularComponent {
638
629
  return JSON.stringify(contextData, null, 2);
639
630
  }
640
631
  static { this.ɵfac = /*@__PURE__*/ (() => { let ɵTemplateParamDialogComponent_BaseFactory; return function TemplateParamDialogComponent_Factory(__ngFactoryType__) { return (ɵTemplateParamDialogComponent_BaseFactory || (ɵTemplateParamDialogComponent_BaseFactory = i0.ɵɵgetInheritedFactory(TemplateParamDialogComponent)))(__ngFactoryType__ || TemplateParamDialogComponent); }; })(); }
641
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TemplateParamDialogComponent, selectors: [["mj-template-param-dialog"]], inputs: { template: "template", isVisible: "isVisible" }, outputs: { isVisibleChange: "isVisibleChange", onClose: "onClose" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [[3, "Visible", "Width"], [3, "Close", "Visible", "Width"], [1, "dialog-content", 2, "display", "flex", "flex-direction", "column", "height", "100%", "font-family", "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif"], [1, "dlg-header"], [1, "dlg-header-row"], [1, "fa-solid", "fa-sliders"], [1, "required-marker"], [1, "dlg-loading"], [2, "display", "flex", "justify-content", "space-between", "align-items", "center", "width", "100%"], ["mjButton", "", "variant", "outline", 3, "disabled"], [2, "display", "flex", "gap", "8px"], ["mjButton", "", "variant", "outline", 3, "click"], ["mjButton", "", "variant", "outline"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [2, "margin-bottom", "16px", "flex-shrink", "0", 3, "ExpandedChange", "Expanded"], ["mjAccordionTitle", ""], [2, "padding", "12px 0"], [1, "dlg-info-text"], [1, "fa-solid", "fa-info-circle"], [1, "params-table"], [1, "no-params-state"], [1, "json-preview-box"], [2, "margin-bottom", "16px", "flex", "1", "display", "flex", "flex-direction", "column", 3, "ExpandedChange", "Expanded"], [2, "padding", "12px 0", "flex", "1", "display", "flex", "flex-direction", "column"], [1, "dlg-loading", 2, "flex", "1"], [2, "flex", "1", "display", "flex", "flex-direction", "column"], [1, "no-results-state"], [1, "dlg-panel-title"], [1, "count-badge"], [1, "params-table-header"], [1, "params-table-row"], [1, "add-param-row"], ["mjButton", "", "variant", "success", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"], [1, "param-name", 2, "display", "flex", "flex-direction", "column"], [2, "display", "flex", "align-items", "center", "gap", "4px", "margin-bottom", "4px"], ["title", "From template definition", 1, "fa-solid", "fa-database", "param-source-icon-template"], ["title", "Custom parameter", 1, "fa-solid", "fa-edit", "param-source-icon-custom"], [1, "param-required-marker"], ["type", "text", "placeholder", "Parameter name...", 1, "mj-input", 2, "font-family", "'Courier New', monospace", "width", "100%", 3, "ngModel", "disabled"], [1, "param-value"], ["placeholder", "Enter value (JSON strings, numbers, objects)...", 1, "mj-textarea", 2, "font-family", "'Courier New', monospace", "font-size", "0.9em", "width", "100%", 3, "ngModelChange", "ngModel", "rows", "disabled"], [1, "param-actions"], ["mjButton", "", "variant", "danger", "size", "sm", "title", "Remove parameter", 3, "disabled"], [1, "param-key-text"], [1, "param-description-text"], [1, "param-type-text"], ["type", "text", "placeholder", "Parameter name...", 1, "mj-input", 2, "font-family", "'Courier New', monospace", "width", "100%", 3, "ngModelChange", "ngModel", "disabled"], ["mjButton", "", "variant", "danger", "size", "sm", "title", "Remove parameter", 3, "click", "disabled"], [1, "fa-solid", "fa-times"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-code"], [1, "fa-solid", "fa-chart-line"], [1, "result-badge", "success"], [1, "result-badge", "error"], [1, "fa-solid", "fa-check"], [1, "result-stats"], [1, "result-stat"], [1, "result-stat-label"], [1, "result-stat-value"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Save results to file", 3, "click"], [1, "fa-solid", "fa-download"], [2, "margin-bottom", "12px", "flex", "1", "display", "flex", "flex-direction", "column"], [1, "output-header"], [1, "fa-solid", "fa-check-circle", "success-icon"], [1, "output-box"], [1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-output-box"], [2, "text-align", "center"], [1, "fa-solid", "fa-play-circle"], ["mjButton", "", "variant", "outline", 3, "click", "disabled"], [1, "fa-solid", "fa-save"], [1, "fa-solid", "fa-play"]], template: function TemplateParamDialogComponent_Template(rf, ctx) { if (rf & 1) {
632
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TemplateParamDialogComponent, selectors: [["mj-template-param-dialog"]], inputs: { template: "template", isVisible: "isVisible" }, outputs: { isVisibleChange: "isVisibleChange", onClose: "onClose" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [[3, "Visible", "Width"], [3, "Close", "Visible", "Width"], [1, "dialog-content", 2, "display", "flex", "flex-direction", "column", "height", "100%", "font-family", "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif"], [1, "dlg-header"], [1, "dlg-header-row"], [1, "fa-solid", "fa-sliders"], [1, "required-marker"], [1, "dlg-loading"], [2, "display", "flex", "justify-content", "space-between", "align-items", "center", "width", "100%"], ["mjButton", "", "variant", "outline", 3, "disabled"], [2, "display", "flex", "gap", "8px"], ["mjButton", "", "variant", "outline", 3, "click"], ["mjButton", "", "variant", "outline"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [2, "margin-bottom", "16px", "flex-shrink", "0", 3, "ExpandedChange", "Expanded"], ["mjAccordionTitle", ""], [2, "padding", "12px 0"], [1, "dlg-info-text"], [1, "fa-solid", "fa-info-circle"], [1, "params-table"], ["Size", "compact", "Icon", "fa-solid fa-circle-info", "Title", "No parameters defined yet"], [1, "json-preview-box"], [2, "margin-bottom", "16px", "flex", "1", "display", "flex", "flex-direction", "column", 3, "ExpandedChange", "Expanded"], [2, "padding", "12px 0", "flex", "1", "display", "flex", "flex-direction", "column"], [1, "dlg-loading", 2, "flex", "1"], [2, "flex", "1", "display", "flex", "flex-direction", "column"], ["Size", "compact", "Icon", "fa-solid fa-circle-play", "Title", "No test results yet. Run the template to see results here.", 1, "no-results-state"], [1, "dlg-panel-title"], [1, "mj-accordion-badge", "mj-accordion-badge--right"], [1, "params-table-header"], [1, "params-table-row"], [1, "add-param-row"], ["mjButton", "", "variant", "success", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"], [1, "param-name", 2, "display", "flex", "flex-direction", "column"], [2, "display", "flex", "align-items", "center", "gap", "4px", "margin-bottom", "4px"], ["title", "From template definition", 1, "fa-solid", "fa-database", "param-source-icon-template"], ["title", "Custom parameter", 1, "fa-solid", "fa-edit", "param-source-icon-custom"], [1, "param-required-marker"], ["type", "text", "placeholder", "Parameter name...", 1, "mj-input", 2, "font-family", "'Courier New', monospace", "width", "100%", 3, "ngModel", "disabled"], [1, "param-value"], ["placeholder", "Enter value (JSON strings, numbers, objects)...", 1, "mj-textarea", 2, "font-family", "'Courier New', monospace", "font-size", "0.9em", "width", "100%", 3, "ngModelChange", "ngModel", "rows", "disabled"], [1, "param-actions"], ["mjButton", "", "variant", "danger", "size", "sm", "title", "Remove parameter", 3, "disabled"], [1, "param-key-text"], [1, "param-description-text"], [1, "param-type-text"], ["type", "text", "placeholder", "Parameter name...", 1, "mj-input", 2, "font-family", "'Courier New', monospace", "width", "100%", 3, "ngModelChange", "ngModel", "disabled"], ["mjButton", "", "variant", "danger", "size", "sm", "title", "Remove parameter", 3, "click", "disabled"], [1, "fa-solid", "fa-times"], ["ngProjectAs", "[actions]", "mjButton", "", "variant", "primary", "size", "sm", 5, ["", "actions", ""], 3, "click", "disabled"], [1, "fa-solid", "fa-code"], [1, "fa-solid", "fa-chart-line"], [1, "result-badge", "success"], [1, "result-badge", "error"], [1, "fa-solid", "fa-check"], [1, "result-stats"], [1, "result-stat"], [1, "result-stat-label"], [1, "result-stat-value"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Save results to file", 3, "click"], [1, "fa-solid", "fa-download"], [2, "margin-bottom", "12px", "flex", "1", "display", "flex", "flex-direction", "column"], [1, "output-header"], [1, "fa-solid", "fa-check-circle", "success-icon"], [1, "output-box"], [1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-output-box"], ["mjButton", "", "variant", "outline", 3, "click", "disabled"], [1, "fa-solid", "fa-save"], [1, "fa-solid", "fa-play"]], template: function TemplateParamDialogComponent_Template(rf, ctx) { if (rf & 1) {
642
633
  i0.ɵɵconditionalCreate(0, TemplateParamDialogComponent_Conditional_0_Template, 27, 8, "mj-dialog", 0);
643
634
  } if (rf & 2) {
644
635
  i0.ɵɵconditional(ctx._isVisible ? 0 : -1);
645
- } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i2.MJAccordionPanelComponent, i2.MJAccordionTitleDirective, i2.MJDialogComponent, i2.MJDialogTitlebarComponent, i2.MJDialogActionsComponent], styles: [".dialog-content[_ngcontent-%COMP%] {\n min-height: 500px;\n max-height: 650px;\n}\n\n.parameter-row[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-card) !important;\n}\n\n.parameter-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.param-name[_ngcontent-%COMP%], \n.param-value[_ngcontent-%COMP%] {\n min-width: 0;\n}\n\n.param-name[_ngcontent-%COMP%] .mj-input[_ngcontent-%COMP%], \n.param-value[_ngcontent-%COMP%] .mj-textarea[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.json-preview[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n line-height: 1.3;\n}\n\n.test-results[_ngcontent-%COMP%] {\n box-shadow: 0 2px 4px var(--mj-shadow-sm);\n}\n\n.result-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n line-height: 1.4;\n}\n\n\n\n.parameters-list[_ngcontent-%COMP%]::-webkit-scrollbar, \n.result-content[_ngcontent-%COMP%]::-webkit-scrollbar, \n.json-preview[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.parameters-list[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.result-content[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.json-preview[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 3px;\n}\n\n.parameters-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.result-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.json-preview[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.parameters-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.result-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.json-preview[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n.parameter-row[_ngcontent-%COMP%] {\n align-items: flex-start;\n}\n\n.parameters-section[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.param-name[_ngcontent-%COMP%] > div[_ngcontent-%COMP%] {\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.header-section[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]:first-child:hover, \n.json-preview-header[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]:first-child:hover, \n.result-header[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-card) !important;\n transition: background-color 0.2s ease;\n}\n\n.fa-chevron-down[_ngcontent-%COMP%], \n.fa-chevron-right[_ngcontent-%COMP%] {\n transition: transform 0.2s ease;\n}\n\n.test-results[_ngcontent-%COMP%] .result-header[_ngcontent-%COMP%] [mjButton][_ngcontent-%COMP%] {\n opacity: 0.8;\n transition: opacity 0.2s ease;\n}\n\n.test-results[_ngcontent-%COMP%] .result-header[_ngcontent-%COMP%]:hover [mjButton][_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n\n\n.dlg-header[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 2px solid var(--mj-border-default);\n}\n\n.dlg-header-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.dlg-header-row[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 1.2em;\n}\n\n.dlg-header-row[_ngcontent-%COMP%] h5[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.dlg-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-muted);\n font-size: 0.9em;\n}\n\n.dlg-header[_ngcontent-%COMP%] .required-marker[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n\n\n.dlg-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.dlg-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: var(--mj-text-muted);\n margin-right: 12px;\n}\n\n.dlg-loading[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.dlg-panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.dlg-panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.dlg-panel-title[_ngcontent-%COMP%] .count-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n}\n\n\n\n.dlg-info-text[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n color: var(--mj-text-muted);\n font-size: 0.85em;\n}\n\n\n\n.params-table[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n}\n\n.params-table-header[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 200px 1fr 60px;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n font-weight: 600;\n font-size: 0.85em;\n color: var(--mj-text-secondary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.params-table-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 200px 1fr 60px;\n gap: 12px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n align-items: start;\n background: var(--mj-bg-surface);\n}\n\n.param-source-icon-template[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-size: 0.75em;\n}\n\n.param-source-icon-custom[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 0.75em;\n}\n\n.param-required-marker[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-weight: bold;\n}\n\n.param-key-text[_ngcontent-%COMP%] {\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 4px 0;\n word-break: break-word;\n}\n\n.param-description-text[_ngcontent-%COMP%] {\n font-size: 0.75em;\n color: var(--mj-text-muted);\n margin-top: 2px;\n font-style: italic;\n word-break: break-word;\n}\n\n.param-type-text[_ngcontent-%COMP%] {\n font-size: 0.7em;\n color: var(--mj-brand-primary);\n margin-top: 2px;\n}\n\n.param-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: start;\n justify-content: center;\n padding-top: 4px;\n}\n\n\n\n.add-param-row[_ngcontent-%COMP%] {\n padding: 12px 16px;\n text-align: center;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n}\n\n\n\n.no-params-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 20px;\n color: var(--mj-text-muted);\n}\n\n.no-params-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2em;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n.no-params-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n}\n\n\n\n.json-preview-box[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 12px;\n font-family: 'Courier New', monospace;\n font-size: 0.85em;\n color: var(--mj-text-primary);\n max-height: 200px;\n overflow-y: auto;\n}\n\n.json-preview-box[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n white-space: pre-wrap;\n}\n\n\n\n.result-badge-success[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n font-weight: 600;\n}\n\n.result-badge-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n font-weight: 600;\n}\n\n\n\n.result-stats[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n padding: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n}\n\n.result-stats.success[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n}\n\n.result-stats.error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n}\n\n.result-stat[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.result-stat-label[_ngcontent-%COMP%] {\n font-size: 0.75em;\n margin-bottom: 2px;\n color: var(--mj-text-muted);\n}\n\n.result-stat-value[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n\n.output-header[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.output-header[_ngcontent-%COMP%] .success-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.output-header[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.output-box[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 12px;\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n white-space: pre-wrap;\n overflow: auto;\n height: 150px;\n color: var(--mj-text-primary);\n}\n\n.error-output-box[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 4px;\n padding: 12px;\n color: var(--mj-status-error);\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n white-space: pre-wrap;\n overflow: auto;\n height: 150px;\n}\n\n\n\n.no-results-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.no-results-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 3em;\n margin-bottom: 12px;\n opacity: 0.3;\n}\n\n.no-results-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n}"] }); }
636
+ } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJEmptyStateComponent, i2.MJButtonDirective, i2.MJAccordionPanelComponent, i2.MJAccordionTitleDirective, i2.MJDialogComponent, i2.MJDialogTitlebarComponent, i2.MJDialogActionsComponent], styles: [".dialog-content[_ngcontent-%COMP%] {\n min-height: 500px;\n max-height: 650px;\n}\n\n.parameter-row[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-card) !important;\n}\n\n.parameter-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.param-name[_ngcontent-%COMP%], \n.param-value[_ngcontent-%COMP%] {\n min-width: 0;\n}\n\n.param-name[_ngcontent-%COMP%] .mj-input[_ngcontent-%COMP%], \n.param-value[_ngcontent-%COMP%] .mj-textarea[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.json-preview[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n line-height: 1.3;\n}\n\n.test-results[_ngcontent-%COMP%] {\n box-shadow: 0 2px 4px var(--mj-shadow-sm);\n}\n\n.result-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n line-height: 1.4;\n}\n\n\n\n.parameters-list[_ngcontent-%COMP%]::-webkit-scrollbar, \n.result-content[_ngcontent-%COMP%]::-webkit-scrollbar, \n.json-preview[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.parameters-list[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.result-content[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.json-preview[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 3px;\n}\n\n.parameters-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.result-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.json-preview[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.parameters-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.result-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.json-preview[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n.parameter-row[_ngcontent-%COMP%] {\n align-items: flex-start;\n}\n\n.parameters-section[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.param-name[_ngcontent-%COMP%] > div[_ngcontent-%COMP%] {\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.header-section[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]:first-child:hover, \n.json-preview-header[_ngcontent-%COMP%] > div[_ngcontent-%COMP%]:first-child:hover, \n.result-header[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-card) !important;\n transition: background-color 0.2s ease;\n}\n\n.fa-chevron-down[_ngcontent-%COMP%], \n.fa-chevron-right[_ngcontent-%COMP%] {\n transition: transform 0.2s ease;\n}\n\n.test-results[_ngcontent-%COMP%] .result-header[_ngcontent-%COMP%] [mjButton][_ngcontent-%COMP%] {\n opacity: 0.8;\n transition: opacity 0.2s ease;\n}\n\n.test-results[_ngcontent-%COMP%] .result-header[_ngcontent-%COMP%]:hover [mjButton][_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n\n\n.dlg-header[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 2px solid var(--mj-border-default);\n}\n\n.dlg-header-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.dlg-header-row[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 1.2em;\n}\n\n.dlg-header-row[_ngcontent-%COMP%] h5[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.dlg-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-muted);\n font-size: 0.9em;\n}\n\n.dlg-header[_ngcontent-%COMP%] .required-marker[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n\n\n.dlg-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.dlg-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: var(--mj-text-muted);\n margin-right: 12px;\n}\n\n.dlg-loading[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.dlg-panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.dlg-panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n\n.dlg-info-text[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n color: var(--mj-text-muted);\n font-size: 0.85em;\n}\n\n\n\n.params-table[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n}\n\n.params-table-header[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 200px 1fr 60px;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n font-weight: 600;\n font-size: 0.85em;\n color: var(--mj-text-secondary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.params-table-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 200px 1fr 60px;\n gap: 12px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n align-items: start;\n background: var(--mj-bg-surface);\n}\n\n.param-source-icon-template[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-size: 0.75em;\n}\n\n.param-source-icon-custom[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 0.75em;\n}\n\n.param-required-marker[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-weight: bold;\n}\n\n.param-key-text[_ngcontent-%COMP%] {\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 4px 0;\n word-break: break-word;\n}\n\n.param-description-text[_ngcontent-%COMP%] {\n font-size: 0.75em;\n color: var(--mj-text-muted);\n margin-top: 2px;\n font-style: italic;\n word-break: break-word;\n}\n\n.param-type-text[_ngcontent-%COMP%] {\n font-size: 0.7em;\n color: var(--mj-brand-primary);\n margin-top: 2px;\n}\n\n.param-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: start;\n justify-content: center;\n padding-top: 4px;\n}\n\n\n\n.add-param-row[_ngcontent-%COMP%] {\n padding: 12px 16px;\n text-align: center;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n}\n\n\n\n.json-preview-box[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 12px;\n font-family: 'Courier New', monospace;\n font-size: 0.85em;\n color: var(--mj-text-primary);\n max-height: 200px;\n overflow-y: auto;\n}\n\n.json-preview-box[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n white-space: pre-wrap;\n}\n\n\n\n.result-badge-success[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n font-weight: 600;\n}\n\n.result-badge-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n font-weight: 600;\n}\n\n\n\n.result-stats[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n padding: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n}\n\n.result-stats.success[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n}\n\n.result-stats.error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n}\n\n.result-stat[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.result-stat-label[_ngcontent-%COMP%] {\n font-size: 0.75em;\n margin-bottom: 2px;\n color: var(--mj-text-muted);\n}\n\n.result-stat-value[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n\n.output-header[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.output-header[_ngcontent-%COMP%] .success-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.output-header[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.output-box[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 12px;\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n white-space: pre-wrap;\n overflow: auto;\n height: 150px;\n color: var(--mj-text-primary);\n}\n\n.error-output-box[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 4px;\n padding: 12px;\n color: var(--mj-status-error);\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n white-space: pre-wrap;\n overflow: auto;\n height: 150px;\n}\n\n\n\nmj-empty-state.no-results-state[_ngcontent-%COMP%] {\n flex: 1;\n}"] }); }
646
637
  }
647
638
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TemplateParamDialogComponent, [{
648
639
  type: Component,
649
- args: [{ standalone: false, selector: 'mj-template-param-dialog', template: "@if (_isVisible) {\n <mj-dialog\n [Visible]=\"true\"\n [Width]=\"800\"\n (Close)=\"close()\">\n <mj-dialog-titlebar>Test Template: {{ template?.Name || 'Unknown' }}</mj-dialog-titlebar>\n <div class=\"dialog-content\" style=\"display: flex; flex-direction: column; height: 100%; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\">\n <!-- Header Section -->\n <div class=\"dlg-header\">\n <div class=\"dlg-header-row\">\n <i class=\"fa-solid fa-sliders\"></i>\n <h5>Template Testing</h5>\n </div>\n <p>\n Configure parameter values for testing. Parameters with <span class=\"required-marker\">*</span> are required.\n </p>\n </div>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"dlg-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading template parameters...</span>\n </div>\n } @else {\n <!-- Template Parameters Section -->\n <mj-accordion-panel\n [(Expanded)]=\"parametersExpanded\"\n style=\"margin-bottom: 16px; flex-shrink: 0;\">\n <ng-template mjAccordionTitle>\n <span class=\"dlg-panel-title\">\n <i class=\"fa-solid fa-sliders\"></i>\n Template Parameters\n @if (parameters.length > 0) {\n <span class=\"count-badge\">{{ parameters.length }}</span>\n }\n </span>\n </ng-template>\n <div style=\"padding: 12px 0;\">\n <div class=\"dlg-info-text\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Configure parameter values for template testing. Values can be JSON objects, strings, or numbers.\n </div>\n <!-- Parameters Table -->\n @if (parameters.length > 0) {\n <div class=\"params-table\">\n <!-- Header -->\n <div class=\"params-table-header\">\n <div>Parameter Name</div>\n <div>Value</div>\n <div>Actions</div>\n </div>\n <!-- Parameter Rows -->\n @for (param of parameters; track $index; let i = $index) {\n <div class=\"params-table-row\">\n <!-- Parameter Name -->\n <div class=\"param-name\" style=\"display: flex; flex-direction: column;\">\n <div style=\"display: flex; align-items: center; gap: 4px; margin-bottom: 4px;\">\n @if (param.isFromTemplate) {\n <i class=\"fa-solid fa-database param-source-icon-template\" title=\"From template definition\"></i>\n } @else {\n <i class=\"fa-solid fa-edit param-source-icon-custom\" title=\"Custom parameter\"></i>\n }\n @if (param.isRequired) {\n <span class=\"param-required-marker\">*</span>\n }\n </div>\n @if (param.isFromTemplate) {\n <div class=\"param-key-text\">\n {{ param.key }}\n </div>\n @if (param.description) {\n <div class=\"param-description-text\">\n {{ param.description }}\n </div>\n }\n @if (param.type && param.type !== 'Scalar') {\n <div class=\"param-type-text\">\n Type: {{ param.type }}\n </div>\n }\n } @else {\n <input type=\"text\" class=\"mj-input\"\n [(ngModel)]=\"param.key\"\n (ngModelChange)=\"onParameterChange()\"\n placeholder=\"Parameter name...\"\n [disabled]=\"isRunning\"\n style=\"font-family: 'Courier New', monospace; width: 100%;\" />\n }\n </div>\n <!-- Parameter Value -->\n <div class=\"param-value\">\n <textarea class=\"mj-textarea\"\n [(ngModel)]=\"param.value\"\n (ngModelChange)=\"onParameterChange()\"\n [rows]=\"2\"\n placeholder=\"Enter value (JSON strings, numbers, objects)...\"\n [disabled]=\"isRunning\"\n style=\"font-family: 'Courier New', monospace; font-size: 0.9em; width: 100%;\"></textarea>\n </div>\n <!-- Actions -->\n <div class=\"param-actions\">\n @if (!param.isFromTemplate && parameters.length > 1) {\n <button mjButton variant=\"danger\" size=\"sm\"\n (click)=\"removeParameter(i)\"\n [disabled]=\"isRunning\"\n title=\"Remove parameter\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n <!-- Add Parameter Row -->\n <div class=\"add-param-row\">\n <button mjButton variant=\"success\" size=\"sm\"\n (click)=\"addParameter()\"\n [disabled]=\"isRunning\">\n <i class=\"fa-solid fa-plus\"></i> Add Parameter\n </button>\n </div>\n </div>\n } @else {\n <div class=\"no-params-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No parameters defined yet</p>\n <button mjButton variant=\"primary\" size=\"sm\"\n (click)=\"addParameter()\"\n [disabled]=\"isRunning\">\n <i class=\"fa-solid fa-plus\"></i> Add First Parameter\n </button>\n </div>\n }\n </div>\n </mj-accordion-panel>\n <!-- JSON Preview Section -->\n <mj-accordion-panel\n [(Expanded)]=\"jsonPreviewExpanded\"\n style=\"margin-bottom: 16px; flex-shrink: 0;\">\n <ng-template mjAccordionTitle>\n <span class=\"dlg-panel-title\">\n <i class=\"fa-solid fa-code\"></i>\n Context Data (JSON)\n </span>\n </ng-template>\n <div style=\"padding: 12px 0;\">\n <div class=\"json-preview-box\">\n <pre>{{ parametersAsJson }}</pre>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Test Results Section -->\n <mj-accordion-panel\n [(Expanded)]=\"resultsExpanded\"\n style=\"margin-bottom: 16px; flex: 1; display: flex; flex-direction: column;\">\n <ng-template mjAccordionTitle>\n <span class=\"dlg-panel-title\">\n <i class=\"fa-solid fa-chart-line\"></i>\n Test Results\n @if (testResult) {\n @if (testResult.success) {\n <span class=\"result-badge success\"><i class=\"fa-solid fa-check\"></i> Success</span>\n } @else {\n <span class=\"result-badge error\"><i class=\"fa-solid fa-times\"></i> Failed</span>\n }\n }\n </span>\n </ng-template>\n <div style=\"padding: 12px 0; flex: 1; display: flex; flex-direction: column;\">\n @if (isRunning) {\n <div class=\"dlg-loading\" style=\"flex: 1;\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Running template...</span>\n </div>\n } @else if (testResult) {\n <div style=\"flex: 1; display: flex; flex-direction: column;\">\n <!-- Result Header with Stats -->\n <div class=\"result-stats\" [class.success]=\"testResult.success\" [class.error]=\"!testResult.success\">\n <div class=\"result-stat\">\n <div class=\"result-stat-label\">STATUS</div>\n <div class=\"result-stat-value\">\n {{ testResult.success ? 'Success' : 'Failed' }}\n </div>\n </div>\n @if (testResult.executionTimeMs) {\n <div class=\"result-stat\">\n <div class=\"result-stat-label\">EXECUTION TIME</div>\n <div class=\"result-stat-value\">{{ testResult.executionTimeMs }}ms</div>\n </div>\n }\n <div class=\"result-stat\">\n <div class=\"result-stat-label\">ACTIONS</div>\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"saveResults()\"\n title=\"Save results to file\">\n <i class=\"fa-solid fa-download\"></i>\n </button>\n </div>\n </div>\n <!-- Result Content -->\n <div style=\"flex: 1; display: flex; flex-direction: column;\">\n @if (testResult.success && testResult.output) {\n <div style=\"margin-bottom: 12px; flex: 1; display: flex; flex-direction: column;\">\n <h6 class=\"output-header\">\n <i class=\"fa-solid fa-check-circle success-icon\"></i>\n Template Output\n </h6>\n <div class=\"output-box\">\n {{ testResult.output }}\n </div>\n </div>\n } @else if (!testResult.success && testResult.error) {\n <div style=\"margin-bottom: 12px; flex: 1; display: flex; flex-direction: column;\">\n <h6 class=\"output-header\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\"></i>\n Error Details\n </h6>\n <div class=\"error-output-box\">{{ testResult.error }}</div>\n </div>\n }\n </div>\n </div>\n } @else {\n <div class=\"no-results-state\">\n <div style=\"text-align: center;\">\n <i class=\"fa-solid fa-play-circle\"></i>\n <p>No test results yet. Run the template to see results here.</p>\n </div>\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n </div>\n <!-- Dialog Actions -->\n <mj-dialog-actions>\n <div style=\"display: flex; justify-content: space-between; align-items: center; width: 100%;\">\n <div>\n @if (hasUnsavedParameters) {\n <button mjButton variant=\"outline\"\n (click)=\"updateTemplateParams()\"\n [disabled]=\"isRunning\">\n <i class=\"fa-solid fa-save\"></i> Update Template Params\n </button>\n }\n </div>\n <div style=\"display: flex; gap: 8px;\">\n <button mjButton variant=\"outline\" (click)=\"close()\">\n Close\n </button>\n @if (testResult) {\n <button mjButton variant=\"outline\" (click)=\"saveResults()\">\n <i class=\"fa-solid fa-download\"></i> Save Results\n </button>\n }\n <button mjButton variant=\"primary\"\n [disabled]=\"isRunning || isLoading\"\n (click)=\"runTemplate()\">\n @if (isRunning) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Running...\n } @else {\n <i class=\"fa-solid fa-play\"></i> Run Template\n }\n </button>\n </div>\n </div>\n </mj-dialog-actions>\n </mj-dialog>\n}\n", styles: [".dialog-content {\n min-height: 500px;\n max-height: 650px;\n}\n\n.parameter-row:hover {\n background-color: var(--mj-bg-surface-card) !important;\n}\n\n.parameter-row:last-child {\n border-bottom: none;\n}\n\n.param-name,\n.param-value {\n min-width: 0;\n}\n\n.param-name .mj-input,\n.param-value .mj-textarea {\n width: 100%;\n}\n\n.json-preview pre {\n line-height: 1.3;\n}\n\n.test-results {\n box-shadow: 0 2px 4px var(--mj-shadow-sm);\n}\n\n.result-content pre {\n line-height: 1.4;\n}\n\n/* Scrollbar styling */\n.parameters-list::-webkit-scrollbar,\n.result-content::-webkit-scrollbar,\n.json-preview > div::-webkit-scrollbar {\n width: 6px;\n}\n\n.parameters-list::-webkit-scrollbar-track,\n.result-content::-webkit-scrollbar-track,\n.json-preview > div::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 3px;\n}\n\n.parameters-list::-webkit-scrollbar-thumb,\n.result-content::-webkit-scrollbar-thumb,\n.json-preview > div::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.parameters-list::-webkit-scrollbar-thumb:hover,\n.result-content::-webkit-scrollbar-thumb:hover,\n.json-preview > div::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n.parameter-row {\n align-items: flex-start;\n}\n\n.parameters-section {\n flex-shrink: 0;\n}\n\n.param-name > div {\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.header-section > div:first-child:hover,\n.json-preview-header > div:first-child:hover,\n.result-header:hover {\n background-color: var(--mj-bg-surface-card) !important;\n transition: background-color 0.2s ease;\n}\n\n.fa-chevron-down,\n.fa-chevron-right {\n transition: transform 0.2s ease;\n}\n\n.test-results .result-header [mjButton] {\n opacity: 0.8;\n transition: opacity 0.2s ease;\n}\n\n.test-results .result-header:hover [mjButton] {\n opacity: 1;\n}\n\n/* Dialog header section */\n.dlg-header {\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 2px solid var(--mj-border-default);\n}\n\n.dlg-header-row {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.dlg-header-row i {\n color: var(--mj-text-muted);\n font-size: 1.2em;\n}\n\n.dlg-header-row h5 {\n margin: 0;\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.dlg-header p {\n margin: 0;\n color: var(--mj-text-muted);\n font-size: 0.9em;\n}\n\n.dlg-header .required-marker {\n color: var(--mj-status-error);\n}\n\n/* Loading state */\n.dlg-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.dlg-loading i {\n font-size: 24px;\n color: var(--mj-text-muted);\n margin-right: 12px;\n}\n\n.dlg-loading span {\n color: var(--mj-text-muted);\n}\n\n/* Panel title */\n.dlg-panel-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.dlg-panel-title i {\n color: var(--mj-text-muted);\n}\n\n.dlg-panel-title .count-badge {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n}\n\n/* Info text */\n.dlg-info-text {\n margin-bottom: 12px;\n color: var(--mj-text-muted);\n font-size: 0.85em;\n}\n\n/* Parameters table */\n.params-table {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n}\n\n.params-table-header {\n display: grid;\n grid-template-columns: 200px 1fr 60px;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n font-weight: 600;\n font-size: 0.85em;\n color: var(--mj-text-secondary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.params-table-row {\n display: grid;\n grid-template-columns: 200px 1fr 60px;\n gap: 12px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n align-items: start;\n background: var(--mj-bg-surface);\n}\n\n.param-source-icon-template {\n color: var(--mj-status-success);\n font-size: 0.75em;\n}\n\n.param-source-icon-custom {\n color: var(--mj-status-warning);\n font-size: 0.75em;\n}\n\n.param-required-marker {\n color: var(--mj-status-error);\n font-weight: bold;\n}\n\n.param-key-text {\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 4px 0;\n word-break: break-word;\n}\n\n.param-description-text {\n font-size: 0.75em;\n color: var(--mj-text-muted);\n margin-top: 2px;\n font-style: italic;\n word-break: break-word;\n}\n\n.param-type-text {\n font-size: 0.7em;\n color: var(--mj-brand-primary);\n margin-top: 2px;\n}\n\n.param-actions {\n display: flex;\n align-items: start;\n justify-content: center;\n padding-top: 4px;\n}\n\n/* Add parameter row */\n.add-param-row {\n padding: 12px 16px;\n text-align: center;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* No params state */\n.no-params-state {\n text-align: center;\n padding: 20px;\n color: var(--mj-text-muted);\n}\n\n.no-params-state i {\n font-size: 2em;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n.no-params-state p {\n margin: 0 0 12px 0;\n}\n\n/* JSON preview */\n.json-preview-box {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 12px;\n font-family: 'Courier New', monospace;\n font-size: 0.85em;\n color: var(--mj-text-primary);\n max-height: 200px;\n overflow-y: auto;\n}\n\n.json-preview-box pre {\n margin: 0;\n white-space: pre-wrap;\n}\n\n/* Result status badges */\n.result-badge-success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n font-weight: 600;\n}\n\n.result-badge-error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n font-weight: 600;\n}\n\n/* Result stats box */\n.result-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n padding: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n}\n\n.result-stats.success {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n}\n\n.result-stats.error {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n}\n\n.result-stat {\n text-align: center;\n}\n\n.result-stat-label {\n font-size: 0.75em;\n margin-bottom: 2px;\n color: var(--mj-text-muted);\n}\n\n.result-stat-value {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* Output section */\n.output-header {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.output-header .success-icon {\n color: var(--mj-status-success);\n}\n\n.output-header .error-icon {\n color: var(--mj-status-error);\n}\n\n.output-box {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 12px;\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n white-space: pre-wrap;\n overflow: auto;\n height: 150px;\n color: var(--mj-text-primary);\n}\n\n.error-output-box {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 4px;\n padding: 12px;\n color: var(--mj-status-error);\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n white-space: pre-wrap;\n overflow: auto;\n height: 150px;\n}\n\n/* No results state */\n.no-results-state {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.no-results-state i {\n font-size: 3em;\n margin-bottom: 12px;\n opacity: 0.3;\n}\n\n.no-results-state p {\n margin: 0;\n}\n"] }]
640
+ args: [{ standalone: false, selector: 'mj-template-param-dialog', template: "@if (_isVisible) {\n <mj-dialog\n [Visible]=\"true\"\n [Width]=\"800\"\n (Close)=\"close()\">\n <mj-dialog-titlebar>Test Template: {{ template?.Name || 'Unknown' }}</mj-dialog-titlebar>\n <div class=\"dialog-content\" style=\"display: flex; flex-direction: column; height: 100%; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\">\n <!-- Header Section -->\n <div class=\"dlg-header\">\n <div class=\"dlg-header-row\">\n <i class=\"fa-solid fa-sliders\"></i>\n <h5>Template Testing</h5>\n </div>\n <p>\n Configure parameter values for testing. Parameters with <span class=\"required-marker\">*</span> are required.\n </p>\n </div>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"dlg-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading template parameters...</span>\n </div>\n } @else {\n <!-- Template Parameters Section -->\n <mj-accordion-panel\n [(Expanded)]=\"parametersExpanded\"\n style=\"margin-bottom: 16px; flex-shrink: 0;\">\n <ng-template mjAccordionTitle>\n <span class=\"dlg-panel-title\">\n <i class=\"fa-solid fa-sliders\"></i>\n Template Parameters\n @if (parameters.length > 0) {\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ parameters.length }}</span>\n }\n </span>\n </ng-template>\n <div style=\"padding: 12px 0;\">\n <div class=\"dlg-info-text\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Configure parameter values for template testing. Values can be JSON objects, strings, or numbers.\n </div>\n <!-- Parameters Table -->\n @if (parameters.length > 0) {\n <div class=\"params-table\">\n <!-- Header -->\n <div class=\"params-table-header\">\n <div>Parameter Name</div>\n <div>Value</div>\n <div>Actions</div>\n </div>\n <!-- Parameter Rows -->\n @for (param of parameters; track $index; let i = $index) {\n <div class=\"params-table-row\">\n <!-- Parameter Name -->\n <div class=\"param-name\" style=\"display: flex; flex-direction: column;\">\n <div style=\"display: flex; align-items: center; gap: 4px; margin-bottom: 4px;\">\n @if (param.isFromTemplate) {\n <i class=\"fa-solid fa-database param-source-icon-template\" title=\"From template definition\"></i>\n } @else {\n <i class=\"fa-solid fa-edit param-source-icon-custom\" title=\"Custom parameter\"></i>\n }\n @if (param.isRequired) {\n <span class=\"param-required-marker\">*</span>\n }\n </div>\n @if (param.isFromTemplate) {\n <div class=\"param-key-text\">\n {{ param.key }}\n </div>\n @if (param.description) {\n <div class=\"param-description-text\">\n {{ param.description }}\n </div>\n }\n @if (param.type && param.type !== 'Scalar') {\n <div class=\"param-type-text\">\n Type: {{ param.type }}\n </div>\n }\n } @else {\n <input type=\"text\" class=\"mj-input\"\n [(ngModel)]=\"param.key\"\n (ngModelChange)=\"onParameterChange()\"\n placeholder=\"Parameter name...\"\n [disabled]=\"isRunning\"\n style=\"font-family: 'Courier New', monospace; width: 100%;\" />\n }\n </div>\n <!-- Parameter Value -->\n <div class=\"param-value\">\n <textarea class=\"mj-textarea\"\n [(ngModel)]=\"param.value\"\n (ngModelChange)=\"onParameterChange()\"\n [rows]=\"2\"\n placeholder=\"Enter value (JSON strings, numbers, objects)...\"\n [disabled]=\"isRunning\"\n style=\"font-family: 'Courier New', monospace; font-size: 0.9em; width: 100%;\"></textarea>\n </div>\n <!-- Actions -->\n <div class=\"param-actions\">\n @if (!param.isFromTemplate && parameters.length > 1) {\n <button mjButton variant=\"danger\" size=\"sm\"\n (click)=\"removeParameter(i)\"\n [disabled]=\"isRunning\"\n title=\"Remove parameter\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n <!-- Add Parameter Row -->\n <div class=\"add-param-row\">\n <button mjButton variant=\"success\" size=\"sm\"\n (click)=\"addParameter()\"\n [disabled]=\"isRunning\">\n <i class=\"fa-solid fa-plus\"></i> Add Parameter\n </button>\n </div>\n </div>\n } @else {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-circle-info\"\n Title=\"No parameters defined yet\">\n <button ngProjectAs=\"[actions]\" mjButton variant=\"primary\" size=\"sm\"\n (click)=\"addParameter()\"\n [disabled]=\"isRunning\">\n <i class=\"fa-solid fa-plus\"></i> Add First Parameter\n </button>\n </mj-empty-state>\n }\n </div>\n </mj-accordion-panel>\n <!-- JSON Preview Section -->\n <mj-accordion-panel\n [(Expanded)]=\"jsonPreviewExpanded\"\n style=\"margin-bottom: 16px; flex-shrink: 0;\">\n <ng-template mjAccordionTitle>\n <span class=\"dlg-panel-title\">\n <i class=\"fa-solid fa-code\"></i>\n Context Data (JSON)\n </span>\n </ng-template>\n <div style=\"padding: 12px 0;\">\n <div class=\"json-preview-box\">\n <pre>{{ parametersAsJson }}</pre>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Test Results Section -->\n <mj-accordion-panel\n [(Expanded)]=\"resultsExpanded\"\n style=\"margin-bottom: 16px; flex: 1; display: flex; flex-direction: column;\">\n <ng-template mjAccordionTitle>\n <span class=\"dlg-panel-title\">\n <i class=\"fa-solid fa-chart-line\"></i>\n Test Results\n @if (testResult) {\n @if (testResult.success) {\n <span class=\"result-badge success\"><i class=\"fa-solid fa-check\"></i> Success</span>\n } @else {\n <span class=\"result-badge error\"><i class=\"fa-solid fa-times\"></i> Failed</span>\n }\n }\n </span>\n </ng-template>\n <div style=\"padding: 12px 0; flex: 1; display: flex; flex-direction: column;\">\n @if (isRunning) {\n <div class=\"dlg-loading\" style=\"flex: 1;\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Running template...</span>\n </div>\n } @else if (testResult) {\n <div style=\"flex: 1; display: flex; flex-direction: column;\">\n <!-- Result Header with Stats -->\n <div class=\"result-stats\" [class.success]=\"testResult.success\" [class.error]=\"!testResult.success\">\n <div class=\"result-stat\">\n <div class=\"result-stat-label\">STATUS</div>\n <div class=\"result-stat-value\">\n {{ testResult.success ? 'Success' : 'Failed' }}\n </div>\n </div>\n @if (testResult.executionTimeMs) {\n <div class=\"result-stat\">\n <div class=\"result-stat-label\">EXECUTION TIME</div>\n <div class=\"result-stat-value\">{{ testResult.executionTimeMs }}ms</div>\n </div>\n }\n <div class=\"result-stat\">\n <div class=\"result-stat-label\">ACTIONS</div>\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"saveResults()\"\n title=\"Save results to file\">\n <i class=\"fa-solid fa-download\"></i>\n </button>\n </div>\n </div>\n <!-- Result Content -->\n <div style=\"flex: 1; display: flex; flex-direction: column;\">\n @if (testResult.success && testResult.output) {\n <div style=\"margin-bottom: 12px; flex: 1; display: flex; flex-direction: column;\">\n <h6 class=\"output-header\">\n <i class=\"fa-solid fa-check-circle success-icon\"></i>\n Template Output\n </h6>\n <div class=\"output-box\">\n {{ testResult.output }}\n </div>\n </div>\n } @else if (!testResult.success && testResult.error) {\n <div style=\"margin-bottom: 12px; flex: 1; display: flex; flex-direction: column;\">\n <h6 class=\"output-header\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\"></i>\n Error Details\n </h6>\n <div class=\"error-output-box\">{{ testResult.error }}</div>\n </div>\n }\n </div>\n </div>\n } @else {\n <mj-empty-state class=\"no-results-state\"\n Size=\"compact\"\n Icon=\"fa-solid fa-circle-play\"\n Title=\"No test results yet. Run the template to see results here.\" />\n }\n </div>\n </mj-accordion-panel>\n }\n </div>\n <!-- Dialog Actions -->\n <mj-dialog-actions>\n <div style=\"display: flex; justify-content: space-between; align-items: center; width: 100%;\">\n <div>\n @if (hasUnsavedParameters) {\n <button mjButton variant=\"outline\"\n (click)=\"updateTemplateParams()\"\n [disabled]=\"isRunning\">\n <i class=\"fa-solid fa-save\"></i> Update Template Params\n </button>\n }\n </div>\n <div style=\"display: flex; gap: 8px;\">\n <button mjButton variant=\"outline\" (click)=\"close()\">\n Close\n </button>\n @if (testResult) {\n <button mjButton variant=\"outline\" (click)=\"saveResults()\">\n <i class=\"fa-solid fa-download\"></i> Save Results\n </button>\n }\n <button mjButton variant=\"primary\"\n [disabled]=\"isRunning || isLoading\"\n (click)=\"runTemplate()\">\n @if (isRunning) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Running...\n } @else {\n <i class=\"fa-solid fa-play\"></i> Run Template\n }\n </button>\n </div>\n </div>\n </mj-dialog-actions>\n </mj-dialog>\n}\n", styles: [".dialog-content {\n min-height: 500px;\n max-height: 650px;\n}\n\n.parameter-row:hover {\n background-color: var(--mj-bg-surface-card) !important;\n}\n\n.parameter-row:last-child {\n border-bottom: none;\n}\n\n.param-name,\n.param-value {\n min-width: 0;\n}\n\n.param-name .mj-input,\n.param-value .mj-textarea {\n width: 100%;\n}\n\n.json-preview pre {\n line-height: 1.3;\n}\n\n.test-results {\n box-shadow: 0 2px 4px var(--mj-shadow-sm);\n}\n\n.result-content pre {\n line-height: 1.4;\n}\n\n/* Scrollbar styling */\n.parameters-list::-webkit-scrollbar,\n.result-content::-webkit-scrollbar,\n.json-preview > div::-webkit-scrollbar {\n width: 6px;\n}\n\n.parameters-list::-webkit-scrollbar-track,\n.result-content::-webkit-scrollbar-track,\n.json-preview > div::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 3px;\n}\n\n.parameters-list::-webkit-scrollbar-thumb,\n.result-content::-webkit-scrollbar-thumb,\n.json-preview > div::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.parameters-list::-webkit-scrollbar-thumb:hover,\n.result-content::-webkit-scrollbar-thumb:hover,\n.json-preview > div::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n.parameter-row {\n align-items: flex-start;\n}\n\n.parameters-section {\n flex-shrink: 0;\n}\n\n.param-name > div {\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.header-section > div:first-child:hover,\n.json-preview-header > div:first-child:hover,\n.result-header:hover {\n background-color: var(--mj-bg-surface-card) !important;\n transition: background-color 0.2s ease;\n}\n\n.fa-chevron-down,\n.fa-chevron-right {\n transition: transform 0.2s ease;\n}\n\n.test-results .result-header [mjButton] {\n opacity: 0.8;\n transition: opacity 0.2s ease;\n}\n\n.test-results .result-header:hover [mjButton] {\n opacity: 1;\n}\n\n/* Dialog header section */\n.dlg-header {\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 2px solid var(--mj-border-default);\n}\n\n.dlg-header-row {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.dlg-header-row i {\n color: var(--mj-text-muted);\n font-size: 1.2em;\n}\n\n.dlg-header-row h5 {\n margin: 0;\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.dlg-header p {\n margin: 0;\n color: var(--mj-text-muted);\n font-size: 0.9em;\n}\n\n.dlg-header .required-marker {\n color: var(--mj-status-error);\n}\n\n/* Loading state */\n.dlg-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.dlg-loading i {\n font-size: 24px;\n color: var(--mj-text-muted);\n margin-right: 12px;\n}\n\n.dlg-loading span {\n color: var(--mj-text-muted);\n}\n\n/* Panel title */\n.dlg-panel-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.dlg-panel-title i {\n color: var(--mj-text-muted);\n}\n\n\n/* Info text */\n.dlg-info-text {\n margin-bottom: 12px;\n color: var(--mj-text-muted);\n font-size: 0.85em;\n}\n\n/* Parameters table */\n.params-table {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n}\n\n.params-table-header {\n display: grid;\n grid-template-columns: 200px 1fr 60px;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n font-weight: 600;\n font-size: 0.85em;\n color: var(--mj-text-secondary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.params-table-row {\n display: grid;\n grid-template-columns: 200px 1fr 60px;\n gap: 12px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n align-items: start;\n background: var(--mj-bg-surface);\n}\n\n.param-source-icon-template {\n color: var(--mj-status-success);\n font-size: 0.75em;\n}\n\n.param-source-icon-custom {\n color: var(--mj-status-warning);\n font-size: 0.75em;\n}\n\n.param-required-marker {\n color: var(--mj-status-error);\n font-weight: bold;\n}\n\n.param-key-text {\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 4px 0;\n word-break: break-word;\n}\n\n.param-description-text {\n font-size: 0.75em;\n color: var(--mj-text-muted);\n margin-top: 2px;\n font-style: italic;\n word-break: break-word;\n}\n\n.param-type-text {\n font-size: 0.7em;\n color: var(--mj-brand-primary);\n margin-top: 2px;\n}\n\n.param-actions {\n display: flex;\n align-items: start;\n justify-content: center;\n padding-top: 4px;\n}\n\n/* Add parameter row */\n.add-param-row {\n padding: 12px 16px;\n text-align: center;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* JSON preview */\n.json-preview-box {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 12px;\n font-family: 'Courier New', monospace;\n font-size: 0.85em;\n color: var(--mj-text-primary);\n max-height: 200px;\n overflow-y: auto;\n}\n\n.json-preview-box pre {\n margin: 0;\n white-space: pre-wrap;\n}\n\n/* Result status badges */\n.result-badge-success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n font-weight: 600;\n}\n\n.result-badge-error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 0.7em;\n font-weight: 600;\n}\n\n/* Result stats box */\n.result-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n padding: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n}\n\n.result-stats.success {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n}\n\n.result-stats.error {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n}\n\n.result-stat {\n text-align: center;\n}\n\n.result-stat-label {\n font-size: 0.75em;\n margin-bottom: 2px;\n color: var(--mj-text-muted);\n}\n\n.result-stat-value {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* Output section */\n.output-header {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.output-header .success-icon {\n color: var(--mj-status-success);\n}\n\n.output-header .error-icon {\n color: var(--mj-status-error);\n}\n\n.output-box {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 12px;\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n white-space: pre-wrap;\n overflow: auto;\n height: 150px;\n color: var(--mj-text-primary);\n}\n\n.error-output-box {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 4px;\n padding: 12px;\n color: var(--mj-status-error);\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n white-space: pre-wrap;\n overflow: auto;\n height: 150px;\n}\n\n/* No results state \u2014 fills the results pane */\nmj-empty-state.no-results-state {\n flex: 1;\n}\n"] }]
650
641
  }], null, { template: [{
651
642
  type: Input
652
643
  }], isVisible: [{