@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.
- package/dist/__tests__/model-prediction.logic.test.d.ts +2 -0
- package/dist/__tests__/model-prediction.logic.test.d.ts.map +1 -0
- package/dist/__tests__/model-prediction.logic.test.js +140 -0
- package/dist/__tests__/model-prediction.logic.test.js.map +1 -0
- package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js +79 -105
- package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js +7 -10
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js +46 -51
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +2 -0
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js +300 -378
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +22 -29
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +15 -17
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +27 -34
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +11 -0
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +48 -47
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +438 -454
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +48 -51
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +253 -282
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.js +24 -33
- package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.js +263 -311
- package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.d.ts +6 -0
- package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.js +475 -493
- package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
- package/dist/lib/custom/Lists/list-form.component.js +122 -173
- package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.js +190 -248
- package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-run-dialog.component.js +19 -23
- package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
- package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js +23 -24
- package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.js +14 -23
- package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.js +100 -130
- package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-form.component.js +187 -205
- package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts +8 -0
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.js +412 -489
- package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.js +100 -126
- package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +166 -184
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +42 -61
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +8 -17
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +0 -2
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +183 -188
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts +108 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js +665 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts +94 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js +257 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts +38 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js +200 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts +44 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js +180 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts +12 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js +46 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts +64 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js +267 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts +53 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js +111 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts +42 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js +193 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js.map +1 -0
- package/dist/lib/custom/custom-forms.module.d.ts +58 -51
- package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
- package/dist/lib/custom/custom-forms.module.js +52 -13
- package/dist/lib/custom/custom-forms.module.js.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +2 -0
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.js +25 -25
- package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +280 -216
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js +25 -21
- package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +68 -14
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js +44 -32
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js +66 -0
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +55 -19
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +28 -10
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js +167 -0
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js +64 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js +82 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js +64 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAction/mjaction.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js +35 -17
- package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js +59 -51
- package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js +25 -7
- package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js +11 -7
- package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +56 -46
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js +73 -59
- package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js +24 -4
- package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +137 -87
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js +47 -29
- package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js +99 -0
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js +101 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js +115 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJFile/mjfile.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +63 -9
- package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js +32 -14
- package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js +161 -0
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js +89 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js +76 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js +141 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js +88 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js +143 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js +110 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js +54 -24
- package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js +24 -6
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js +36 -18
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js +8 -6
- package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js +78 -0
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +145 -109
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
- package/dist/lib/generated/generated-forms.module.d.ts +356 -335
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +304 -226
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/dist/lib/panels/ai-agents/agent-realtime.panel.js +44 -44
- package/dist/lib/panels/ai-agents/agent-realtime.panel.js.map +1 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts +43 -0
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts.map +1 -0
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js +240 -0
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +69 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.js +130 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts +83 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.js +293 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -0
- package/package.json +38 -37
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts +0 -82
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts.map +0 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js +0 -1033
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js.map +0 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ElementRef, EventEmitter, OnDestroy } from '@angular/core';
|
|
2
|
+
import { FlowModel, FlowNode } from './agent-run-flow.model';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Flowchart — a clean, static top-down tree of the run (the evolution of the old
|
|
6
|
+
* Visualization tab). No clock: pan (drag), zoom (wheel / buttons), click a node to
|
|
7
|
+
* inspect it (click again or the background to deselect), and collapse/expand
|
|
8
|
+
* sub-agent & loop containers. Built on the same shared FlowModel as the animated
|
|
9
|
+
* renderers, so palette, hierarchy and durations stay consistent.
|
|
10
|
+
*/
|
|
11
|
+
export declare class FlowchartComponent implements OnDestroy {
|
|
12
|
+
svgRef: ElementRef<SVGSVGElement>;
|
|
13
|
+
nodeSelected: EventEmitter<FlowNode>;
|
|
14
|
+
selectionCleared: EventEmitter<void>;
|
|
15
|
+
private _model;
|
|
16
|
+
private built;
|
|
17
|
+
private listening;
|
|
18
|
+
private boxes;
|
|
19
|
+
private mainG?;
|
|
20
|
+
private selectedId;
|
|
21
|
+
private collapsed;
|
|
22
|
+
private readonly NODE_W;
|
|
23
|
+
private readonly NODE_H;
|
|
24
|
+
private readonly VGAP;
|
|
25
|
+
private readonly INDENT;
|
|
26
|
+
private readonly PADX;
|
|
27
|
+
private view;
|
|
28
|
+
private panning;
|
|
29
|
+
private moved;
|
|
30
|
+
private suppressBg;
|
|
31
|
+
private start;
|
|
32
|
+
set Model(m: FlowModel | null);
|
|
33
|
+
Render(_p: number, _ts: number): void;
|
|
34
|
+
ngOnDestroy(): void;
|
|
35
|
+
private clear;
|
|
36
|
+
private visibleNodes;
|
|
37
|
+
private descendantCount;
|
|
38
|
+
private buildScene;
|
|
39
|
+
private toggleCollapse;
|
|
40
|
+
private onWheel;
|
|
41
|
+
private onDown;
|
|
42
|
+
private onDownPos;
|
|
43
|
+
private onMove;
|
|
44
|
+
private onUp;
|
|
45
|
+
private attachListeners;
|
|
46
|
+
private detachListeners;
|
|
47
|
+
private applyView;
|
|
48
|
+
private zoomAt;
|
|
49
|
+
private fitToView;
|
|
50
|
+
zoomIn(): void;
|
|
51
|
+
zoomOut(): void;
|
|
52
|
+
resetView(): void;
|
|
53
|
+
ZoomIn(): void;
|
|
54
|
+
ZoomOut(): void;
|
|
55
|
+
FitReset(): void;
|
|
56
|
+
private onNodeClick;
|
|
57
|
+
private deselect;
|
|
58
|
+
/** External deselect (e.g. detail panel closed) — clears highlight without re-emitting. */
|
|
59
|
+
Deselect(): void;
|
|
60
|
+
private paintSelection;
|
|
61
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FlowchartComponent, never>;
|
|
62
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FlowchartComponent, "mj-agent-flow-flowchart", never, { "Model": { "alias": "Model"; "required": false; }; }, { "nodeSelected": "nodeSelected"; "selectionCleared": "selectionCleared"; }, never, never, false, never>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=flowchart.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flowchart.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/flowchart.component.ts"],"names":[],"mappings":"AAAA,OAAO,EACM,UAAU,EAAiB,YAAY,EACN,SAAS,EACtD,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAuD,MAAM,wBAAwB,CAAC;;AAKlH;;;;;;GAMG;AACH,qBAQa,kBAAmB,YAAW,SAAS;IACd,MAAM,EAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAC7D,YAAY,yBAAgC;IAC5C,gBAAgB,qBAA4B;IAEtD,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,KAAK,CAAC,CAAa;IAC3B,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,SAAS,CAAqB;IAEtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAO;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAM;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAM;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAM;IAE3B,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAgC;IAE7C,IAAa,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,EAAsG;IAErI,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAK5C,WAAW,IAAI,IAAI;IAEnB,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,UAAU;IAwElB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,OAAO,CAIb;IACF,OAAO,CAAC,MAAM,CAAsJ;IACpK,OAAO,CAAC,SAAS,CAAoF;IACrG,OAAO,CAAC,MAAM,CAMZ;IACF,OAAO,CAAC,IAAI,CAGV;IAEF,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,SAAS;IAGjB,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,SAAS;IAUV,MAAM,IAAI,IAAI;IACd,OAAO,IAAI,IAAI;IACf,SAAS,IAAI,IAAI;IAGjB,MAAM,IAAI,IAAI;IACd,OAAO,IAAI,IAAI;IACf,QAAQ,IAAI,IAAI;IAIvB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,QAAQ;IAOhB,2FAA2F;IACpF,QAAQ,IAAI,IAAI;IAKvB,OAAO,CAAC,cAAc;yCAtNX,kBAAkB;2CAAlB,kBAAkB;CA6N9B"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, ViewChild, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
|
|
2
|
+
import { FLOW_COLORS, FLOW_LABEL, shortLabel, formatDuration } from './agent-run-flow.model';
|
|
3
|
+
import { svgEl, clip, appendIcon, appendTitle } from './flow-svg.util';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
const _c0 = ["svg"];
|
|
6
|
+
/**
|
|
7
|
+
* Flowchart — a clean, static top-down tree of the run (the evolution of the old
|
|
8
|
+
* Visualization tab). No clock: pan (drag), zoom (wheel / buttons), click a node to
|
|
9
|
+
* inspect it (click again or the background to deselect), and collapse/expand
|
|
10
|
+
* sub-agent & loop containers. Built on the same shared FlowModel as the animated
|
|
11
|
+
* renderers, so palette, hierarchy and durations stay consistent.
|
|
12
|
+
*/
|
|
13
|
+
export class FlowchartComponent {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.nodeSelected = new EventEmitter();
|
|
16
|
+
this.selectionCleared = new EventEmitter();
|
|
17
|
+
this._model = null;
|
|
18
|
+
this.built = false;
|
|
19
|
+
this.listening = false;
|
|
20
|
+
this.boxes = new Map();
|
|
21
|
+
this.selectedId = -1;
|
|
22
|
+
this.collapsed = new Set();
|
|
23
|
+
this.NODE_W = 280;
|
|
24
|
+
this.NODE_H = 62;
|
|
25
|
+
this.VGAP = 22;
|
|
26
|
+
this.INDENT = 48;
|
|
27
|
+
this.PADX = 40;
|
|
28
|
+
this.view = { s: 1, tx: 0, ty: 0 };
|
|
29
|
+
this.panning = false;
|
|
30
|
+
this.moved = false;
|
|
31
|
+
this.suppressBg = false;
|
|
32
|
+
this.start = { x: 0, y: 0, tx: 0, ty: 0 };
|
|
33
|
+
/* ------------------------------ pan / zoom ------------------------------- */
|
|
34
|
+
this.onWheel = (e) => {
|
|
35
|
+
e.preventDefault();
|
|
36
|
+
const r = this.svgRef.nativeElement.getBoundingClientRect();
|
|
37
|
+
this.zoomAt(e.clientX - r.left, e.clientY - r.top, e.deltaY > 0 ? 0.9 : 1.1);
|
|
38
|
+
};
|
|
39
|
+
this.onDown = () => { this.panning = true; this.moved = false; this.suppressBg = false; this.start = { x: 0, y: 0, tx: this.view.tx, ty: this.view.ty }; };
|
|
40
|
+
this.onDownPos = (e) => { this.start.x = e.clientX; this.start.y = e.clientY; };
|
|
41
|
+
this.onMove = (e) => {
|
|
42
|
+
if (!this.panning)
|
|
43
|
+
return;
|
|
44
|
+
const dx = e.clientX - this.start.x, dy = e.clientY - this.start.y;
|
|
45
|
+
if (Math.abs(dx) + Math.abs(dy) > 3)
|
|
46
|
+
this.moved = true;
|
|
47
|
+
this.view.tx = this.start.tx + dx;
|
|
48
|
+
this.view.ty = this.start.ty + dy;
|
|
49
|
+
this.applyView();
|
|
50
|
+
};
|
|
51
|
+
this.onUp = () => {
|
|
52
|
+
if (this.panning && !this.moved && !this.suppressBg)
|
|
53
|
+
this.deselect();
|
|
54
|
+
this.panning = false;
|
|
55
|
+
this.suppressBg = false;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
set Model(m) { this._model = m; this.built = false; this.collapsed.clear(); this.selectedId = -1; this.clear(); }
|
|
59
|
+
Render(_p, _ts) {
|
|
60
|
+
if (!this._model)
|
|
61
|
+
return;
|
|
62
|
+
if (!this.built) {
|
|
63
|
+
this.buildScene(true);
|
|
64
|
+
this.built = true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
ngOnDestroy() { this.detachListeners(); }
|
|
68
|
+
clear() {
|
|
69
|
+
const svg = this.svgRef?.nativeElement;
|
|
70
|
+
if (svg)
|
|
71
|
+
while (svg.firstChild)
|
|
72
|
+
svg.removeChild(svg.firstChild);
|
|
73
|
+
this.boxes.clear();
|
|
74
|
+
}
|
|
75
|
+
/* ------------------------------ scene build ------------------------------ */
|
|
76
|
+
visibleNodes() {
|
|
77
|
+
const out = [];
|
|
78
|
+
const walk = (n) => { out.push(n); if (!this.collapsed.has(n.id))
|
|
79
|
+
n.children.forEach(walk); };
|
|
80
|
+
walk(this._model.root);
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
descendantCount(n) {
|
|
84
|
+
return n.children.reduce((s, c) => s + 1 + this.descendantCount(c), 0);
|
|
85
|
+
}
|
|
86
|
+
buildScene(fit) {
|
|
87
|
+
this.clear();
|
|
88
|
+
const svg = this.svgRef.nativeElement;
|
|
89
|
+
const ordered = this.visibleNodes();
|
|
90
|
+
const rowY = (i) => i * (this.NODE_H + this.VGAP);
|
|
91
|
+
this.mainG = svgEl('g', {}, svg);
|
|
92
|
+
const main = this.mainG;
|
|
93
|
+
const edges = svgEl('g', {}, main);
|
|
94
|
+
const nodesG = svgEl('g', {}, main);
|
|
95
|
+
const pos = new Map();
|
|
96
|
+
ordered.forEach((n, i) => pos.set(n.id, { x: this.PADX + n.depth * this.INDENT, y: rowY(i) }));
|
|
97
|
+
// elbow connectors to parent (file-tree style)
|
|
98
|
+
for (const n of ordered) {
|
|
99
|
+
if (!n.parent || !pos.has(n.parent.id))
|
|
100
|
+
continue;
|
|
101
|
+
const c = pos.get(n.id), p = pos.get(n.parent.id);
|
|
102
|
+
const spineX = p.x + 16, midY = c.y + this.NODE_H / 2;
|
|
103
|
+
svgEl('path', { d: `M${spineX},${p.y + this.NODE_H} L${spineX},${midY} L${c.x},${midY}`, fill: 'none', stroke: 'var(--mj-border-strong)', 'stroke-width': 1.5 }, edges);
|
|
104
|
+
}
|
|
105
|
+
for (const n of ordered) {
|
|
106
|
+
const { x, y } = pos.get(n.id);
|
|
107
|
+
const col = FLOW_COLORS[n.type];
|
|
108
|
+
const isContainer = n.children.length > 0;
|
|
109
|
+
const isCollapsed = this.collapsed.has(n.id);
|
|
110
|
+
const grp = svgEl('g', {}, nodesG);
|
|
111
|
+
grp.style.color = col;
|
|
112
|
+
const body = svgEl('g', {}, grp);
|
|
113
|
+
body.style.cursor = 'pointer';
|
|
114
|
+
const sel = n.id === this.selectedId;
|
|
115
|
+
const rect = svgEl('rect', {
|
|
116
|
+
x, y, width: this.NODE_W, height: this.NODE_H, rx: 12,
|
|
117
|
+
fill: sel ? 'var(--mj-bg-surface-hover)' : 'var(--mj-bg-surface-card)',
|
|
118
|
+
stroke: col, 'stroke-width': sel ? 3 : isContainer ? 2 : 1.4, opacity: 0.98
|
|
119
|
+
}, body);
|
|
120
|
+
if (n.heat >= 2)
|
|
121
|
+
rect.setAttribute('class', 'glow' + n.heat);
|
|
122
|
+
svgEl('rect', { x, y, width: 5, height: this.NODE_H, rx: 2.5, fill: col }, body);
|
|
123
|
+
appendTitle(body, `${n.name} · ${formatDuration(n.realDur)}`);
|
|
124
|
+
appendIcon(body, x + 14, y + this.NODE_H / 2 - 11, 22, n.iconClass, n.logoUrl, col);
|
|
125
|
+
svgEl('text', { x: x + 46, y: y + 22, 'font-size': 13, 'font-weight': 600, 'dominant-baseline': 'middle', text: clip(shortLabel(n), 26) }, body);
|
|
126
|
+
const baseSub = n.model ? `${FLOW_LABEL[n.type]} · ${n.model}` : FLOW_LABEL[n.type];
|
|
127
|
+
const sub = isContainer && isCollapsed ? `${FLOW_LABEL[n.type]} · ${this.descendantCount(n)} hidden` : baseSub;
|
|
128
|
+
svgEl('text', { x: x + 46, y: y + 41, 'font-size': 10.5, class: 'ftxt-muted', text: clip(sub, 32) }, body);
|
|
129
|
+
if (n.realDur) {
|
|
130
|
+
svgEl('text', { x: x + this.NODE_W - 14, y: y + this.NODE_H / 2, 'font-size': 11, 'font-weight': 600, 'text-anchor': 'end', 'dominant-baseline': 'middle', class: 'ftxt-secondary', text: formatDuration(n.realDur) }, body);
|
|
131
|
+
}
|
|
132
|
+
body.addEventListener('mouseup', () => { if (!this.moved) {
|
|
133
|
+
this.suppressBg = true;
|
|
134
|
+
this.onNodeClick(n);
|
|
135
|
+
} });
|
|
136
|
+
// collapse / expand disclosure — in the LEFT gutter, tree convention
|
|
137
|
+
if (isContainer) {
|
|
138
|
+
const gx = x - 15, gy = y + this.NODE_H / 2;
|
|
139
|
+
const tg = svgEl('g', {}, grp);
|
|
140
|
+
tg.style.cursor = 'pointer';
|
|
141
|
+
svgEl('circle', { cx: gx, cy: gy, r: 9, fill: 'transparent' }, tg); // hit target
|
|
142
|
+
const tri = isCollapsed
|
|
143
|
+
? `M${gx - 3},${gy - 5} L${gx + 4},${gy} L${gx - 3},${gy + 5} Z`
|
|
144
|
+
: `M${gx - 5},${gy - 3} L${gx + 5},${gy - 3} L${gx},${gy + 4} Z`;
|
|
145
|
+
svgEl('path', { d: tri, fill: col }, tg);
|
|
146
|
+
tg.addEventListener('mouseup', () => { if (!this.moved) {
|
|
147
|
+
this.suppressBg = true;
|
|
148
|
+
this.toggleCollapse(n);
|
|
149
|
+
} });
|
|
150
|
+
}
|
|
151
|
+
this.boxes.set(n.id, { rect, node: n });
|
|
152
|
+
}
|
|
153
|
+
if (!this.listening) {
|
|
154
|
+
this.attachListeners();
|
|
155
|
+
this.listening = true;
|
|
156
|
+
}
|
|
157
|
+
if (fit)
|
|
158
|
+
requestAnimationFrame(() => this.fitToView());
|
|
159
|
+
else
|
|
160
|
+
this.applyView();
|
|
161
|
+
}
|
|
162
|
+
toggleCollapse(n) {
|
|
163
|
+
if (this.collapsed.has(n.id))
|
|
164
|
+
this.collapsed.delete(n.id);
|
|
165
|
+
else
|
|
166
|
+
this.collapsed.add(n.id);
|
|
167
|
+
this.buildScene(false);
|
|
168
|
+
}
|
|
169
|
+
attachListeners() {
|
|
170
|
+
const svg = this.svgRef.nativeElement;
|
|
171
|
+
svg.addEventListener('wheel', this.onWheel, { passive: false });
|
|
172
|
+
svg.addEventListener('mousedown', (e) => { this.onDown(); this.onDownPos(e); });
|
|
173
|
+
window.addEventListener('mousemove', this.onMove);
|
|
174
|
+
window.addEventListener('mouseup', this.onUp);
|
|
175
|
+
}
|
|
176
|
+
detachListeners() {
|
|
177
|
+
const svg = this.svgRef?.nativeElement;
|
|
178
|
+
svg?.removeEventListener('wheel', this.onWheel);
|
|
179
|
+
window.removeEventListener('mousemove', this.onMove);
|
|
180
|
+
window.removeEventListener('mouseup', this.onUp);
|
|
181
|
+
}
|
|
182
|
+
applyView() {
|
|
183
|
+
this.mainG?.setAttribute('transform', `translate(${this.view.tx},${this.view.ty}) scale(${this.view.s})`);
|
|
184
|
+
}
|
|
185
|
+
zoomAt(cx, cy, factor) {
|
|
186
|
+
const ns = Math.max(0.2, Math.min(2.5, this.view.s * factor));
|
|
187
|
+
this.view.tx = cx - (cx - this.view.tx) * (ns / this.view.s);
|
|
188
|
+
this.view.ty = cy - (cy - this.view.ty) * (ns / this.view.s);
|
|
189
|
+
this.view.s = ns;
|
|
190
|
+
this.applyView();
|
|
191
|
+
}
|
|
192
|
+
fitToView() {
|
|
193
|
+
const svg = this.svgRef.nativeElement;
|
|
194
|
+
if (!this.mainG)
|
|
195
|
+
return;
|
|
196
|
+
const bb = this.mainG.getBBox();
|
|
197
|
+
const vw = svg.clientWidth || 900, vh = svg.clientHeight || 600;
|
|
198
|
+
const s = Math.max(0.25, Math.min(1.15, Math.min((vw - 60) / Math.max(1, bb.width), (vh - 48) / Math.max(1, bb.height))));
|
|
199
|
+
this.view = { s, tx: (vw - bb.width * s) / 2 - bb.x * s, ty: 28 - bb.y * s };
|
|
200
|
+
this.applyView();
|
|
201
|
+
}
|
|
202
|
+
zoomIn() { const svg = this.svgRef.nativeElement; this.zoomAt(svg.clientWidth / 2, svg.clientHeight / 2, 1.2); }
|
|
203
|
+
zoomOut() { const svg = this.svgRef.nativeElement; this.zoomAt(svg.clientWidth / 2, svg.clientHeight / 2, 1 / 1.2); }
|
|
204
|
+
resetView() { this.fitToView(); }
|
|
205
|
+
// unified interface used by the container's shared zoom toolbar
|
|
206
|
+
ZoomIn() { this.zoomIn(); }
|
|
207
|
+
ZoomOut() { this.zoomOut(); }
|
|
208
|
+
FitReset() { this.fitToView(); }
|
|
209
|
+
/* ------------------------------- selection ------------------------------ */
|
|
210
|
+
onNodeClick(n) {
|
|
211
|
+
if (this.selectedId === n.id) {
|
|
212
|
+
this.deselect();
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
this.selectedId = n.id;
|
|
216
|
+
this.paintSelection();
|
|
217
|
+
this.nodeSelected.emit(n);
|
|
218
|
+
}
|
|
219
|
+
deselect() {
|
|
220
|
+
if (this.selectedId === -1)
|
|
221
|
+
return;
|
|
222
|
+
this.selectedId = -1;
|
|
223
|
+
this.paintSelection();
|
|
224
|
+
this.selectionCleared.emit();
|
|
225
|
+
}
|
|
226
|
+
/** External deselect (e.g. detail panel closed) — clears highlight without re-emitting. */
|
|
227
|
+
Deselect() {
|
|
228
|
+
if (this.selectedId === -1)
|
|
229
|
+
return;
|
|
230
|
+
this.selectedId = -1;
|
|
231
|
+
this.paintSelection();
|
|
232
|
+
}
|
|
233
|
+
paintSelection() {
|
|
234
|
+
this.boxes.forEach(({ rect, node }) => {
|
|
235
|
+
const sel = node.id === this.selectedId;
|
|
236
|
+
rect.setAttribute('stroke-width', sel ? '3' : node.children.length ? '2' : '1.4');
|
|
237
|
+
rect.setAttribute('fill', sel ? 'var(--mj-bg-surface-hover)' : 'var(--mj-bg-surface-card)');
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
static { this.ɵfac = function FlowchartComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FlowchartComponent)(); }; }
|
|
241
|
+
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FlowchartComponent, selectors: [["mj-agent-flow-flowchart"]], viewQuery: function FlowchartComponent_Query(rf, ctx) { if (rf & 1) {
|
|
242
|
+
i0.ɵɵviewQuery(_c0, 7);
|
|
243
|
+
} if (rf & 2) {
|
|
244
|
+
let _t;
|
|
245
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.svgRef = _t.first);
|
|
246
|
+
} }, inputs: { Model: "Model" }, outputs: { nodeSelected: "nodeSelected", selectionCleared: "selectionCleared" }, standalone: false, decls: 3, vars: 0, consts: [["svg", ""], [1, "fc-wrap"], [1, "flow-svg"]], template: function FlowchartComponent_Template(rf, ctx) { if (rf & 1) {
|
|
247
|
+
i0.ɵɵelementStart(0, "div", 1);
|
|
248
|
+
i0.ɵɵnamespaceSVG();
|
|
249
|
+
i0.ɵɵelement(1, "svg", 2, 0);
|
|
250
|
+
i0.ɵɵelementEnd();
|
|
251
|
+
} }, styles: ["/* ViewEncapsulation.None \u2014 namespaced under .fc-* to avoid leakage. */\nmj-agent-flow-flowchart { display: block; width: 100%; height: 100%; }\n\n.fc-wrap { position: relative; width: 100%; height: 100%; }\n\n.fc-toolbar {\n position: absolute;\n top: 12px;\n right: 14px;\n display: flex;\n gap: 6px;\n z-index: 3;\n}\n.fc-btn {\n width: 34px;\n height: 34px;\n border-radius: 9px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n cursor: pointer;\n display: grid;\n place-items: center;\n font-size: 13px;\n}\n.fc-btn:hover { color: var(--mj-text-primary); border-color: var(--mj-brand-primary); }\n\n.fc-wrap .flow-svg { cursor: grab; }\n.fc-wrap .flow-svg:active { cursor: grabbing; }\n", "/* Shared chrome for every flow renderer's <svg> host.\n These components use ViewEncapsulation.None so this CSS reaches SVG nodes\n created imperatively via createElementNS (which never receive Angular's\n emulated-encapsulation scoping attribute). Everything is namespaced under\n `.flow-svg` to avoid leaking into the rest of the app. */\n.flow-svg {\n width: 100%;\n height: 100%;\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.flow-svg text { fill: var(--mj-text-primary); }\n.flow-svg .ftxt-secondary { fill: var(--mj-text-secondary); }\n.flow-svg .ftxt-muted { fill: var(--mj-text-muted); }\n.flow-svg .ftxt-on { fill: var(--mj-text-inverse); }\n.flow-svg .fgrid { stroke: var(--mj-border-subtle); }\n.flow-svg .fhand { stroke: var(--mj-text-secondary); }\n.flow-svg .fhand-dot { fill: var(--mj-text-primary); }\n.flow-svg .fstar-bg { fill: var(--mj-text-muted); }\n/* outlined label for legibility over edges / busy fields */\n.flow-svg .fhalo { paint-order: stroke; stroke: var(--mj-bg-page); stroke-width: 3.5px; stroke-linejoin: round; }\n\n/* Heat / activity glow tiers \u2014 driven by `currentColor` (the node's category color). */\n.flow-svg .glow1 { filter: drop-shadow(0 0 4px currentColor); }\n.flow-svg .glow2 { filter: drop-shadow(0 0 9px currentColor); }\n.flow-svg .glow3 { filter: drop-shadow(0 0 16px currentColor); }\n"], encapsulation: 2, changeDetection: 0 }); }
|
|
252
|
+
}
|
|
253
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FlowchartComponent, [{
|
|
254
|
+
type: Component,
|
|
255
|
+
args: [{ standalone: false, selector: 'mj-agent-flow-flowchart', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fc-wrap\">\n <svg #svg class=\"flow-svg\"></svg>\n</div>\n", styles: ["/* ViewEncapsulation.None \u2014 namespaced under .fc-* to avoid leakage. */\nmj-agent-flow-flowchart { display: block; width: 100%; height: 100%; }\n\n.fc-wrap { position: relative; width: 100%; height: 100%; }\n\n.fc-toolbar {\n position: absolute;\n top: 12px;\n right: 14px;\n display: flex;\n gap: 6px;\n z-index: 3;\n}\n.fc-btn {\n width: 34px;\n height: 34px;\n border-radius: 9px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n cursor: pointer;\n display: grid;\n place-items: center;\n font-size: 13px;\n}\n.fc-btn:hover { color: var(--mj-text-primary); border-color: var(--mj-brand-primary); }\n\n.fc-wrap .flow-svg { cursor: grab; }\n.fc-wrap .flow-svg:active { cursor: grabbing; }\n", "/* Shared chrome for every flow renderer's <svg> host.\n These components use ViewEncapsulation.None so this CSS reaches SVG nodes\n created imperatively via createElementNS (which never receive Angular's\n emulated-encapsulation scoping attribute). Everything is namespaced under\n `.flow-svg` to avoid leaking into the rest of the app. */\n.flow-svg {\n width: 100%;\n height: 100%;\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.flow-svg text { fill: var(--mj-text-primary); }\n.flow-svg .ftxt-secondary { fill: var(--mj-text-secondary); }\n.flow-svg .ftxt-muted { fill: var(--mj-text-muted); }\n.flow-svg .ftxt-on { fill: var(--mj-text-inverse); }\n.flow-svg .fgrid { stroke: var(--mj-border-subtle); }\n.flow-svg .fhand { stroke: var(--mj-text-secondary); }\n.flow-svg .fhand-dot { fill: var(--mj-text-primary); }\n.flow-svg .fstar-bg { fill: var(--mj-text-muted); }\n/* outlined label for legibility over edges / busy fields */\n.flow-svg .fhalo { paint-order: stroke; stroke: var(--mj-bg-page); stroke-width: 3.5px; stroke-linejoin: round; }\n\n/* Heat / activity glow tiers \u2014 driven by `currentColor` (the node's category color). */\n.flow-svg .glow1 { filter: drop-shadow(0 0 4px currentColor); }\n.flow-svg .glow2 { filter: drop-shadow(0 0 9px currentColor); }\n.flow-svg .glow3 { filter: drop-shadow(0 0 16px currentColor); }\n"] }]
|
|
256
|
+
}], null, { svgRef: [{
|
|
257
|
+
type: ViewChild,
|
|
258
|
+
args: ['svg', { static: true }]
|
|
259
|
+
}], nodeSelected: [{
|
|
260
|
+
type: Output
|
|
261
|
+
}], selectionCleared: [{
|
|
262
|
+
type: Output
|
|
263
|
+
}], Model: [{
|
|
264
|
+
type: Input
|
|
265
|
+
}] }); })();
|
|
266
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FlowchartComponent, { className: "FlowchartComponent", filePath: "src/lib/custom/ai-agent-run/flow/flowchart.component.ts", lineNumber: 25 }); })();
|
|
267
|
+
//# sourceMappingURL=flowchart.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flowchart.component.js","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/flowchart.component.ts","../../../../../src/lib/custom/ai-agent-run/flow/flowchart.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component, ElementRef, Input, Output, EventEmitter, ViewChild,\n ChangeDetectionStrategy, ViewEncapsulation, OnDestroy\n} from '@angular/core';\nimport { FlowModel, FlowNode, FLOW_COLORS, FLOW_LABEL, shortLabel, formatDuration } from './agent-run-flow.model';\nimport { svgEl, clip, appendIcon, appendTitle } from './flow-svg.util';\n\ninterface Box { rect: SVGElement; node: FlowNode; }\n\n/**\n * Flowchart — a clean, static top-down tree of the run (the evolution of the old\n * Visualization tab). No clock: pan (drag), zoom (wheel / buttons), click a node to\n * inspect it (click again or the background to deselect), and collapse/expand\n * sub-agent & loop containers. Built on the same shared FlowModel as the animated\n * renderers, so palette, hierarchy and durations stay consistent.\n */\n@Component({\n standalone: false,\n selector: 'mj-agent-flow-flowchart',\n templateUrl: './flowchart.component.html',\n styleUrls: ['./flowchart.component.css', './flow-shared.css'],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class FlowchartComponent implements OnDestroy {\n @ViewChild('svg', { static: true }) svgRef!: ElementRef<SVGSVGElement>;\n @Output() nodeSelected = new EventEmitter<FlowNode>();\n @Output() selectionCleared = new EventEmitter<void>();\n\n private _model: FlowModel | null = null;\n private built = false;\n private listening = false;\n private boxes = new Map<number, Box>();\n private mainG?: SVGElement;\n private selectedId = -1;\n private collapsed = new Set<number>();\n\n private readonly NODE_W = 280;\n private readonly NODE_H = 62;\n private readonly VGAP = 22;\n private readonly INDENT = 48;\n private readonly PADX = 40;\n\n private view = { s: 1, tx: 0, ty: 0 };\n private panning = false;\n private moved = false;\n private suppressBg = false;\n private start = { x: 0, y: 0, tx: 0, ty: 0 };\n\n @Input() set Model(m: FlowModel | null) { this._model = m; this.built = false; this.collapsed.clear(); this.selectedId = -1; this.clear(); }\n\n public Render(_p: number, _ts: number): void {\n if (!this._model) return;\n if (!this.built) { this.buildScene(true); this.built = true; }\n }\n\n ngOnDestroy(): void { this.detachListeners(); }\n\n private clear(): void {\n const svg = this.svgRef?.nativeElement;\n if (svg) while (svg.firstChild) svg.removeChild(svg.firstChild);\n this.boxes.clear();\n }\n\n /* ------------------------------ scene build ------------------------------ */\n\n private visibleNodes(): FlowNode[] {\n const out: FlowNode[] = [];\n const walk = (n: FlowNode) => { out.push(n); if (!this.collapsed.has(n.id)) n.children.forEach(walk); };\n walk(this._model!.root);\n return out;\n }\n\n private descendantCount(n: FlowNode): number {\n return n.children.reduce((s, c) => s + 1 + this.descendantCount(c), 0);\n }\n\n private buildScene(fit: boolean): void {\n this.clear();\n const svg = this.svgRef.nativeElement;\n const ordered = this.visibleNodes();\n const rowY = (i: number) => i * (this.NODE_H + this.VGAP);\n\n this.mainG = svgEl('g', {}, svg);\n const main = this.mainG;\n const edges = svgEl('g', {}, main);\n const nodesG = svgEl('g', {}, main);\n\n const pos = new Map<number, { x: number; y: number }>();\n ordered.forEach((n, i) => pos.set(n.id, { x: this.PADX + n.depth * this.INDENT, y: rowY(i) }));\n\n // elbow connectors to parent (file-tree style)\n for (const n of ordered) {\n if (!n.parent || !pos.has(n.parent.id)) continue;\n const c = pos.get(n.id)!, p = pos.get(n.parent.id)!;\n const spineX = p.x + 16, midY = c.y + this.NODE_H / 2;\n svgEl('path', { d: `M${spineX},${p.y + this.NODE_H} L${spineX},${midY} L${c.x},${midY}`, fill: 'none', stroke: 'var(--mj-border-strong)', 'stroke-width': 1.5 }, edges);\n }\n\n for (const n of ordered) {\n const { x, y } = pos.get(n.id)!;\n const col = FLOW_COLORS[n.type];\n const isContainer = n.children.length > 0;\n const isCollapsed = this.collapsed.has(n.id);\n const grp = svgEl('g', {}, nodesG);\n (grp as SVGElement & { style: CSSStyleDeclaration }).style.color = col;\n\n const body = svgEl('g', {}, grp);\n (body as SVGElement & { style: CSSStyleDeclaration }).style.cursor = 'pointer';\n const sel = n.id === this.selectedId;\n const rect = svgEl('rect', {\n x, y, width: this.NODE_W, height: this.NODE_H, rx: 12,\n fill: sel ? 'var(--mj-bg-surface-hover)' : 'var(--mj-bg-surface-card)',\n stroke: col, 'stroke-width': sel ? 3 : isContainer ? 2 : 1.4, opacity: 0.98\n }, body);\n if (n.heat >= 2) rect.setAttribute('class', 'glow' + n.heat);\n svgEl('rect', { x, y, width: 5, height: this.NODE_H, rx: 2.5, fill: col }, body);\n appendTitle(body, `${n.name} · ${formatDuration(n.realDur)}`);\n appendIcon(body, x + 14, y + this.NODE_H / 2 - 11, 22, n.iconClass, n.logoUrl, col);\n svgEl('text', { x: x + 46, y: y + 22, 'font-size': 13, 'font-weight': 600, 'dominant-baseline': 'middle', text: clip(shortLabel(n), 26) }, body);\n const baseSub = n.model ? `${FLOW_LABEL[n.type]} · ${n.model}` : FLOW_LABEL[n.type];\n const sub = isContainer && isCollapsed ? `${FLOW_LABEL[n.type]} · ${this.descendantCount(n)} hidden` : baseSub;\n svgEl('text', { x: x + 46, y: y + 41, 'font-size': 10.5, class: 'ftxt-muted', text: clip(sub, 32) }, body);\n if (n.realDur) {\n svgEl('text', { x: x + this.NODE_W - 14, y: y + this.NODE_H / 2, 'font-size': 11, 'font-weight': 600, 'text-anchor': 'end', 'dominant-baseline': 'middle', class: 'ftxt-secondary', text: formatDuration(n.realDur) }, body);\n }\n body.addEventListener('mouseup', () => { if (!this.moved) { this.suppressBg = true; this.onNodeClick(n); } });\n\n // collapse / expand disclosure — in the LEFT gutter, tree convention\n if (isContainer) {\n const gx = x - 15, gy = y + this.NODE_H / 2;\n const tg = svgEl('g', {}, grp);\n (tg as SVGElement & { style: CSSStyleDeclaration }).style.cursor = 'pointer';\n svgEl('circle', { cx: gx, cy: gy, r: 9, fill: 'transparent' }, tg); // hit target\n const tri = isCollapsed\n ? `M${gx - 3},${gy - 5} L${gx + 4},${gy} L${gx - 3},${gy + 5} Z`\n : `M${gx - 5},${gy - 3} L${gx + 5},${gy - 3} L${gx},${gy + 4} Z`;\n svgEl('path', { d: tri, fill: col }, tg);\n tg.addEventListener('mouseup', () => { if (!this.moved) { this.suppressBg = true; this.toggleCollapse(n); } });\n }\n\n this.boxes.set(n.id, { rect, node: n });\n }\n\n if (!this.listening) { this.attachListeners(); this.listening = true; }\n if (fit) requestAnimationFrame(() => this.fitToView());\n else this.applyView();\n }\n\n private toggleCollapse(n: FlowNode): void {\n if (this.collapsed.has(n.id)) this.collapsed.delete(n.id); else this.collapsed.add(n.id);\n this.buildScene(false);\n }\n\n /* ------------------------------ pan / zoom ------------------------------- */\n\n private onWheel = (e: WheelEvent): void => {\n e.preventDefault();\n const r = this.svgRef.nativeElement.getBoundingClientRect();\n this.zoomAt(e.clientX - r.left, e.clientY - r.top, e.deltaY > 0 ? 0.9 : 1.1);\n };\n private onDown = (): void => { this.panning = true; this.moved = false; this.suppressBg = false; this.start = { x: 0, y: 0, tx: this.view.tx, ty: this.view.ty }; };\n private onDownPos = (e: MouseEvent): void => { this.start.x = e.clientX; this.start.y = e.clientY; };\n private onMove = (e: MouseEvent): void => {\n if (!this.panning) return;\n const dx = e.clientX - this.start.x, dy = e.clientY - this.start.y;\n if (Math.abs(dx) + Math.abs(dy) > 3) this.moved = true;\n this.view.tx = this.start.tx + dx; this.view.ty = this.start.ty + dy;\n this.applyView();\n };\n private onUp = (): void => {\n if (this.panning && !this.moved && !this.suppressBg) this.deselect();\n this.panning = false; this.suppressBg = false;\n };\n\n private attachListeners(): void {\n const svg = this.svgRef.nativeElement;\n svg.addEventListener('wheel', this.onWheel, { passive: false });\n svg.addEventListener('mousedown', (e) => { this.onDown(); this.onDownPos(e); });\n window.addEventListener('mousemove', this.onMove);\n window.addEventListener('mouseup', this.onUp);\n }\n private detachListeners(): void {\n const svg = this.svgRef?.nativeElement;\n svg?.removeEventListener('wheel', this.onWheel);\n window.removeEventListener('mousemove', this.onMove);\n window.removeEventListener('mouseup', this.onUp);\n }\n\n private applyView(): void {\n this.mainG?.setAttribute('transform', `translate(${this.view.tx},${this.view.ty}) scale(${this.view.s})`);\n }\n private zoomAt(cx: number, cy: number, factor: number): void {\n const ns = Math.max(0.2, Math.min(2.5, this.view.s * factor));\n this.view.tx = cx - (cx - this.view.tx) * (ns / this.view.s);\n this.view.ty = cy - (cy - this.view.ty) * (ns / this.view.s);\n this.view.s = ns; this.applyView();\n }\n private fitToView(): void {\n const svg = this.svgRef.nativeElement;\n if (!this.mainG) return;\n const bb = (this.mainG as SVGGraphicsElement).getBBox();\n const vw = svg.clientWidth || 900, vh = svg.clientHeight || 600;\n const s = Math.max(0.25, Math.min(1.15, Math.min((vw - 60) / Math.max(1, bb.width), (vh - 48) / Math.max(1, bb.height))));\n this.view = { s, tx: (vw - bb.width * s) / 2 - bb.x * s, ty: 28 - bb.y * s };\n this.applyView();\n }\n\n public zoomIn(): void { const svg = this.svgRef.nativeElement; this.zoomAt(svg.clientWidth / 2, svg.clientHeight / 2, 1.2); }\n public zoomOut(): void { const svg = this.svgRef.nativeElement; this.zoomAt(svg.clientWidth / 2, svg.clientHeight / 2, 1 / 1.2); }\n public resetView(): void { this.fitToView(); }\n\n // unified interface used by the container's shared zoom toolbar\n public ZoomIn(): void { this.zoomIn(); }\n public ZoomOut(): void { this.zoomOut(); }\n public FitReset(): void { this.fitToView(); }\n\n /* ------------------------------- selection ------------------------------ */\n\n private onNodeClick(n: FlowNode): void {\n if (this.selectedId === n.id) { this.deselect(); return; }\n this.selectedId = n.id;\n this.paintSelection();\n this.nodeSelected.emit(n);\n }\n private deselect(): void {\n if (this.selectedId === -1) return;\n this.selectedId = -1;\n this.paintSelection();\n this.selectionCleared.emit();\n }\n\n /** External deselect (e.g. detail panel closed) — clears highlight without re-emitting. */\n public Deselect(): void {\n if (this.selectedId === -1) return;\n this.selectedId = -1;\n this.paintSelection();\n }\n private paintSelection(): void {\n this.boxes.forEach(({ rect, node }) => {\n const sel = node.id === this.selectedId;\n rect.setAttribute('stroke-width', sel ? '3' : node.children.length ? '2' : '1.4');\n rect.setAttribute('fill', sel ? 'var(--mj-bg-surface-hover)' : 'var(--mj-bg-surface-card)');\n });\n }\n}\n","<div class=\"fc-wrap\">\n <svg #svg class=\"flow-svg\"></svg>\n</div>\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
interface View {
|
|
2
|
+
s: number;
|
|
3
|
+
tx: number;
|
|
4
|
+
ty: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Reusable pan/zoom for the viewBox-based flow renderers (Flame, Subway,
|
|
8
|
+
* Constellation). Wheel zooms about the cursor, drag pans, and the view is
|
|
9
|
+
* persisted per-user (cross-device) via UserInfoEngine under `storageKey`.
|
|
10
|
+
*
|
|
11
|
+
* All math is done in the svg's *viewBox* coordinate space (screen deltas are
|
|
12
|
+
* converted), so zoom-to-cursor and pan stay accurate regardless of how the
|
|
13
|
+
* svg is scaled to fit its container.
|
|
14
|
+
*/
|
|
15
|
+
export declare class PanZoomController {
|
|
16
|
+
private svg;
|
|
17
|
+
private group;
|
|
18
|
+
private storageKey;
|
|
19
|
+
private minS;
|
|
20
|
+
private maxS;
|
|
21
|
+
view: View;
|
|
22
|
+
/** True when the last gesture actually dragged — renderers use it to suppress click-select. */
|
|
23
|
+
moved: boolean;
|
|
24
|
+
private panning;
|
|
25
|
+
private startX;
|
|
26
|
+
private startY;
|
|
27
|
+
private startTx;
|
|
28
|
+
private startTy;
|
|
29
|
+
private readonly onWheelB;
|
|
30
|
+
private readonly onDownB;
|
|
31
|
+
private readonly onMoveB;
|
|
32
|
+
private readonly onUpB;
|
|
33
|
+
constructor(svg: SVGSVGElement, group: SVGElement, storageKey: string, minS?: number, maxS?: number);
|
|
34
|
+
Load(): void;
|
|
35
|
+
Attach(): void;
|
|
36
|
+
Detach(): void;
|
|
37
|
+
ZoomIn(): void;
|
|
38
|
+
ZoomOut(): void;
|
|
39
|
+
Reset(): void;
|
|
40
|
+
/** Re-assert this controller's own view onto its group (defensive on mode switch). */
|
|
41
|
+
Reapply(): void;
|
|
42
|
+
private vb;
|
|
43
|
+
private toVbScale;
|
|
44
|
+
private onWheel;
|
|
45
|
+
private onDown;
|
|
46
|
+
private onMove;
|
|
47
|
+
private onUp;
|
|
48
|
+
private zoomAt;
|
|
49
|
+
private apply;
|
|
50
|
+
private persist;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=pan-zoom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pan-zoom.d.ts","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/pan-zoom.ts"],"names":[],"mappings":"AAEA,UAAU,IAAI;IAAG,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;CAAE;AAErD;;;;;;;;GAQG;AACH,qBAAa,iBAAiB;IAiB1B,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,IAAI;IApBP,IAAI,EAAE,IAAI,CAA0B;IAC3C,+FAA+F;IACxF,KAAK,UAAS;IAErB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,OAAO,CAAK;IAEpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwB;gBAGpC,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,SAAM,EACV,IAAI,SAAI;IAGX,IAAI,IAAI,IAAI;IAWZ,MAAM,IAAI,IAAI;IAQd,MAAM,IAAI,IAAI;IAOd,MAAM,IAAI,IAAI;IACd,OAAO,IAAI,IAAI;IACf,KAAK,IAAI,IAAI;IACpB,sFAAsF;IAC/E,OAAO,IAAI,IAAI;IAEtB,OAAO,CAAC,EAAE;IAIV,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,IAAI;IAEZ,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,KAAK;IAGb,OAAO,CAAC,OAAO;CAGhB"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { UserInfoEngine } from '@memberjunction/core-entities';
|
|
2
|
+
/**
|
|
3
|
+
* Reusable pan/zoom for the viewBox-based flow renderers (Flame, Subway,
|
|
4
|
+
* Constellation). Wheel zooms about the cursor, drag pans, and the view is
|
|
5
|
+
* persisted per-user (cross-device) via UserInfoEngine under `storageKey`.
|
|
6
|
+
*
|
|
7
|
+
* All math is done in the svg's *viewBox* coordinate space (screen deltas are
|
|
8
|
+
* converted), so zoom-to-cursor and pan stay accurate regardless of how the
|
|
9
|
+
* svg is scaled to fit its container.
|
|
10
|
+
*/
|
|
11
|
+
export class PanZoomController {
|
|
12
|
+
constructor(svg, group, storageKey, minS = 0.4, maxS = 6) {
|
|
13
|
+
this.svg = svg;
|
|
14
|
+
this.group = group;
|
|
15
|
+
this.storageKey = storageKey;
|
|
16
|
+
this.minS = minS;
|
|
17
|
+
this.maxS = maxS;
|
|
18
|
+
this.view = { s: 1, tx: 0, ty: 0 };
|
|
19
|
+
/** True when the last gesture actually dragged — renderers use it to suppress click-select. */
|
|
20
|
+
this.moved = false;
|
|
21
|
+
this.panning = false;
|
|
22
|
+
this.startX = 0;
|
|
23
|
+
this.startY = 0;
|
|
24
|
+
this.startTx = 0;
|
|
25
|
+
this.startTy = 0;
|
|
26
|
+
this.onWheelB = this.onWheel.bind(this);
|
|
27
|
+
this.onDownB = this.onDown.bind(this);
|
|
28
|
+
this.onMoveB = this.onMove.bind(this);
|
|
29
|
+
this.onUpB = this.onUp.bind(this);
|
|
30
|
+
}
|
|
31
|
+
Load() {
|
|
32
|
+
const raw = UserInfoEngine.Instance.GetSetting(this.storageKey);
|
|
33
|
+
if (!raw)
|
|
34
|
+
return;
|
|
35
|
+
try {
|
|
36
|
+
const v = JSON.parse(raw);
|
|
37
|
+
if (v && typeof v.s === 'number' && typeof v.tx === 'number' && typeof v.ty === 'number') {
|
|
38
|
+
this.view = { s: v.s, tx: v.tx, ty: v.ty };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { /* ignore bad cache */ }
|
|
42
|
+
}
|
|
43
|
+
Attach() {
|
|
44
|
+
this.svg.addEventListener('wheel', this.onWheelB, { passive: false });
|
|
45
|
+
this.svg.addEventListener('mousedown', this.onDownB);
|
|
46
|
+
window.addEventListener('mousemove', this.onMoveB);
|
|
47
|
+
window.addEventListener('mouseup', this.onUpB);
|
|
48
|
+
this.apply();
|
|
49
|
+
}
|
|
50
|
+
Detach() {
|
|
51
|
+
this.svg.removeEventListener('wheel', this.onWheelB);
|
|
52
|
+
this.svg.removeEventListener('mousedown', this.onDownB);
|
|
53
|
+
window.removeEventListener('mousemove', this.onMoveB);
|
|
54
|
+
window.removeEventListener('mouseup', this.onUpB);
|
|
55
|
+
}
|
|
56
|
+
ZoomIn() { const vb = this.vb(); this.zoomAt(vb.w / 2, vb.h / 2, 1.25); }
|
|
57
|
+
ZoomOut() { const vb = this.vb(); this.zoomAt(vb.w / 2, vb.h / 2, 1 / 1.25); }
|
|
58
|
+
Reset() { this.view = { s: 1, tx: 0, ty: 0 }; this.apply(); this.persist(); }
|
|
59
|
+
/** Re-assert this controller's own view onto its group (defensive on mode switch). */
|
|
60
|
+
Reapply() { this.apply(); }
|
|
61
|
+
vb() {
|
|
62
|
+
const b = this.svg.viewBox?.baseVal;
|
|
63
|
+
return b && b.width ? { w: b.width, h: b.height } : { w: this.svg.clientWidth || 1, h: this.svg.clientHeight || 1 };
|
|
64
|
+
}
|
|
65
|
+
toVbScale() {
|
|
66
|
+
const r = this.svg.getBoundingClientRect();
|
|
67
|
+
return r.width ? this.vb().w / r.width : 1;
|
|
68
|
+
}
|
|
69
|
+
onWheel(e) {
|
|
70
|
+
e.preventDefault();
|
|
71
|
+
const r = this.svg.getBoundingClientRect();
|
|
72
|
+
const k = this.toVbScale();
|
|
73
|
+
this.zoomAt((e.clientX - r.left) * k, (e.clientY - r.top) * k, e.deltaY > 0 ? 0.9 : 1.1);
|
|
74
|
+
}
|
|
75
|
+
onDown(e) {
|
|
76
|
+
this.panning = true;
|
|
77
|
+
this.moved = false;
|
|
78
|
+
this.startX = e.clientX;
|
|
79
|
+
this.startY = e.clientY;
|
|
80
|
+
this.startTx = this.view.tx;
|
|
81
|
+
this.startTy = this.view.ty;
|
|
82
|
+
}
|
|
83
|
+
onMove(e) {
|
|
84
|
+
if (!this.panning)
|
|
85
|
+
return;
|
|
86
|
+
const k = this.toVbScale();
|
|
87
|
+
const dx = (e.clientX - this.startX) * k, dy = (e.clientY - this.startY) * k;
|
|
88
|
+
if (Math.abs(dx) + Math.abs(dy) > 3)
|
|
89
|
+
this.moved = true;
|
|
90
|
+
this.view.tx = this.startTx + dx;
|
|
91
|
+
this.view.ty = this.startTy + dy;
|
|
92
|
+
this.apply();
|
|
93
|
+
}
|
|
94
|
+
onUp() { if (this.panning && this.moved)
|
|
95
|
+
this.persist(); this.panning = false; }
|
|
96
|
+
zoomAt(cx, cy, factor) {
|
|
97
|
+
const ns = Math.max(this.minS, Math.min(this.maxS, this.view.s * factor));
|
|
98
|
+
this.view.tx = cx - (cx - this.view.tx) * (ns / this.view.s);
|
|
99
|
+
this.view.ty = cy - (cy - this.view.ty) * (ns / this.view.s);
|
|
100
|
+
this.view.s = ns;
|
|
101
|
+
this.apply();
|
|
102
|
+
this.persist();
|
|
103
|
+
}
|
|
104
|
+
apply() {
|
|
105
|
+
this.group.setAttribute('transform', `translate(${this.view.tx},${this.view.ty}) scale(${this.view.s})`);
|
|
106
|
+
}
|
|
107
|
+
persist() {
|
|
108
|
+
UserInfoEngine.Instance.SetSettingDebounced(this.storageKey, JSON.stringify(this.view));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=pan-zoom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pan-zoom.js","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/pan-zoom.ts"],"names":[],"mappings":"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","sourcesContent":["import { UserInfoEngine } from '@memberjunction/core-entities';\n\ninterface View { s: number; tx: number; ty: number; }\n\n/**\n * Reusable pan/zoom for the viewBox-based flow renderers (Flame, Subway,\n * Constellation). Wheel zooms about the cursor, drag pans, and the view is\n * persisted per-user (cross-device) via UserInfoEngine under `storageKey`.\n *\n * All math is done in the svg's *viewBox* coordinate space (screen deltas are\n * converted), so zoom-to-cursor and pan stay accurate regardless of how the\n * svg is scaled to fit its container.\n */\nexport class PanZoomController {\n public view: View = { s: 1, tx: 0, ty: 0 };\n /** True when the last gesture actually dragged — renderers use it to suppress click-select. */\n public moved = false;\n\n private panning = false;\n private startX = 0;\n private startY = 0;\n private startTx = 0;\n private startTy = 0;\n\n private readonly onWheelB = this.onWheel.bind(this);\n private readonly onDownB = this.onDown.bind(this);\n private readonly onMoveB = this.onMove.bind(this);\n private readonly onUpB = this.onUp.bind(this);\n\n constructor(\n private svg: SVGSVGElement,\n private group: SVGElement,\n private storageKey: string,\n private minS = 0.4,\n private maxS = 6\n ) {}\n\n public Load(): void {\n const raw = UserInfoEngine.Instance.GetSetting(this.storageKey);\n if (!raw) return;\n try {\n const v = JSON.parse(raw) as Partial<View>;\n if (v && typeof v.s === 'number' && typeof v.tx === 'number' && typeof v.ty === 'number') {\n this.view = { s: v.s, tx: v.tx, ty: v.ty };\n }\n } catch { /* ignore bad cache */ }\n }\n\n public Attach(): void {\n this.svg.addEventListener('wheel', this.onWheelB, { passive: false });\n this.svg.addEventListener('mousedown', this.onDownB);\n window.addEventListener('mousemove', this.onMoveB);\n window.addEventListener('mouseup', this.onUpB);\n this.apply();\n }\n\n public Detach(): void {\n this.svg.removeEventListener('wheel', this.onWheelB);\n this.svg.removeEventListener('mousedown', this.onDownB);\n window.removeEventListener('mousemove', this.onMoveB);\n window.removeEventListener('mouseup', this.onUpB);\n }\n\n public ZoomIn(): void { const vb = this.vb(); this.zoomAt(vb.w / 2, vb.h / 2, 1.25); }\n public ZoomOut(): void { const vb = this.vb(); this.zoomAt(vb.w / 2, vb.h / 2, 1 / 1.25); }\n public Reset(): void { this.view = { s: 1, tx: 0, ty: 0 }; this.apply(); this.persist(); }\n /** Re-assert this controller's own view onto its group (defensive on mode switch). */\n public Reapply(): void { this.apply(); }\n\n private vb(): { w: number; h: number } {\n const b = this.svg.viewBox?.baseVal;\n return b && b.width ? { w: b.width, h: b.height } : { w: this.svg.clientWidth || 1, h: this.svg.clientHeight || 1 };\n }\n private toVbScale(): number {\n const r = this.svg.getBoundingClientRect();\n return r.width ? this.vb().w / r.width : 1;\n }\n\n private onWheel(e: WheelEvent): void {\n e.preventDefault();\n const r = this.svg.getBoundingClientRect();\n const k = this.toVbScale();\n this.zoomAt((e.clientX - r.left) * k, (e.clientY - r.top) * k, e.deltaY > 0 ? 0.9 : 1.1);\n }\n private onDown(e: MouseEvent): void {\n this.panning = true; this.moved = false;\n this.startX = e.clientX; this.startY = e.clientY;\n this.startTx = this.view.tx; this.startTy = this.view.ty;\n }\n private onMove(e: MouseEvent): void {\n if (!this.panning) return;\n const k = this.toVbScale();\n const dx = (e.clientX - this.startX) * k, dy = (e.clientY - this.startY) * k;\n if (Math.abs(dx) + Math.abs(dy) > 3) this.moved = true;\n this.view.tx = this.startTx + dx; this.view.ty = this.startTy + dy;\n this.apply();\n }\n private onUp(): void { if (this.panning && this.moved) this.persist(); this.panning = false; }\n\n private zoomAt(cx: number, cy: number, factor: number): void {\n const ns = Math.max(this.minS, Math.min(this.maxS, this.view.s * factor));\n this.view.tx = cx - (cx - this.view.tx) * (ns / this.view.s);\n this.view.ty = cy - (cy - this.view.ty) * (ns / this.view.s);\n this.view.s = ns;\n this.apply(); this.persist();\n }\n private apply(): void {\n this.group.setAttribute('transform', `translate(${this.view.tx},${this.view.ty}) scale(${this.view.s})`);\n }\n private persist(): void {\n UserInfoEngine.Instance.SetSettingDebounced(this.storageKey, JSON.stringify(this.view));\n }\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ElementRef, EventEmitter, OnDestroy } from '@angular/core';
|
|
2
|
+
import { FlowModel, FlowNode } from './agent-run-flow.model';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Subway Lines — each agent is a transit line; sub-agents branch off and rejoin.
|
|
6
|
+
* Connectors carry the line's (agent's) colour and brighten as the train passes,
|
|
7
|
+
* so you can follow a sub-agent's route end to end. Stations show the real step
|
|
8
|
+
* icon; labels are abbreviated and angled 30° so dense lines stay readable.
|
|
9
|
+
*/
|
|
10
|
+
export declare class SubwayLinesComponent implements OnDestroy {
|
|
11
|
+
svgRef: ElementRef<SVGSVGElement>;
|
|
12
|
+
nodeSelected: EventEmitter<FlowNode>;
|
|
13
|
+
private _model;
|
|
14
|
+
private built;
|
|
15
|
+
private stations;
|
|
16
|
+
private connectors;
|
|
17
|
+
private train?;
|
|
18
|
+
private trainHalo?;
|
|
19
|
+
private selectedId;
|
|
20
|
+
private pz?;
|
|
21
|
+
ZoomIn(): void;
|
|
22
|
+
ZoomOut(): void;
|
|
23
|
+
FitReset(): void;
|
|
24
|
+
ReapplyView(): void;
|
|
25
|
+
ngOnDestroy(): void;
|
|
26
|
+
private readonly VW;
|
|
27
|
+
private readonly PAD;
|
|
28
|
+
private readonly TOP;
|
|
29
|
+
private readonly LINE_GAP;
|
|
30
|
+
private readonly DWELL;
|
|
31
|
+
private readonly MIN_LABEL_GAP;
|
|
32
|
+
private get IW();
|
|
33
|
+
SetSelected(id: number | null): void;
|
|
34
|
+
set Model(m: FlowModel | null);
|
|
35
|
+
Render(p: number, ts: number): void;
|
|
36
|
+
private clear;
|
|
37
|
+
private build;
|
|
38
|
+
private update;
|
|
39
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SubwayLinesComponent, never>;
|
|
40
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SubwayLinesComponent, "mj-agent-flow-subway", never, { "Model": { "alias": "Model"; "required": false; }; }, { "nodeSelected": "nodeSelected"; }, never, never, false, never>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=subway-lines.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subway-lines.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/subway-lines.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAiB,YAAY,EAAa,SAAS,EAA8C,MAAM,eAAe,CAAC;AACrJ,OAAO,EACL,SAAS,EAAE,QAAQ,EACpB,MAAM,wBAAwB,CAAC;;AAOhC;;;;;GAKG;AACH,qBAQa,oBAAqB,YAAW,SAAS;IAChB,MAAM,EAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAC7D,YAAY,yBAAgC;IAEtD,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,KAAK,CAAC,CAAa;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,EAAE,CAAC,CAAoB;IAExB,MAAM,IAAI,IAAI;IACd,OAAO,IAAI,IAAI;IACf,QAAQ,IAAI,IAAI;IAChB,WAAW,IAAI,IAAI;IAC1B,WAAW,IAAI,IAAI;IAEnB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAQ;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAO;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAO;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAO;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAM;IACpC,OAAO,KAAK,EAAE,GAA8C;IAErD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAE3C,IAAa,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,EAAwD;IAEvF,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAM1C,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,KAAK;IA6Eb,OAAO,CAAC,MAAM;yCAzHH,oBAAoB;2CAApB,oBAAoB;CAoKhC"}
|