@memberjunction/ng-core-entity-forms 6.2.0-edge.0 → 6.2.0-edge.1
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/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.d.ts +1 -1
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.js +2 -2
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.js.map +1 -1
- package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts +90 -16
- package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js +218 -70
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts +80 -16
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js +146 -46
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +329 -27
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js +794 -262
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-management.service.d.ts +76 -0
- package/dist/lib/custom/AIAgents/ai-agent-management.service.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-management.service.js +77 -33
- package/dist/lib/custom/AIAgents/ai-agent-management.service.js.map +1 -1
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts +69 -15
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js +182 -74
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts +105 -25
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +272 -112
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts +32 -6
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +71 -19
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.service.d.ts +10 -0
- package/dist/lib/custom/AIAgents/new-agent-dialog.service.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.service.js +27 -7
- package/dist/lib/custom/AIAgents/new-agent-dialog.service.js.map +1 -1
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts +65 -15
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +152 -52
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts +81 -15
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js +145 -45
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +71 -17
- 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 +175 -67
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts +173 -27
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +385 -93
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.d.ts +64 -4
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +129 -29
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts +260 -27
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +686 -238
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-management.service.d.ts +10 -0
- package/dist/lib/custom/AIPrompts/ai-prompt-management.service.d.ts.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-management.service.js +17 -9
- package/dist/lib/custom/AIPrompts/ai-prompt-management.service.js.map +1 -1
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts +74 -16
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js +174 -58
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.d.ts +108 -14
- package/dist/lib/custom/Actions/action-execution-log-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.js +258 -70
- package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.d.ts +198 -14
- package/dist/lib/custom/Actions/action-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.js +387 -107
- package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
- package/dist/lib/custom/BridgeProviders/bridge-provider-features.d.ts +12 -6
- package/dist/lib/custom/BridgeProviders/bridge-provider-features.d.ts.map +1 -1
- package/dist/lib/custom/BridgeProviders/bridge-provider-features.js +41 -29
- package/dist/lib/custom/BridgeProviders/bridge-provider-features.js.map +1 -1
- package/dist/lib/custom/BridgeProviders/bridge-provider-form.component.js +14 -14
- package/dist/lib/custom/BridgeProviders/bridge-provider-form.component.js.map +1 -1
- package/dist/lib/custom/Companies/company-overview.panel.d.ts +1 -1
- package/dist/lib/custom/Companies/company-overview.panel.js +2 -2
- package/dist/lib/custom/Companies/company-overview.panel.js.map +1 -1
- package/dist/lib/custom/Conversations/conversation-overview.panel.d.ts +1 -1
- package/dist/lib/custom/Conversations/conversation-overview.panel.js +2 -2
- package/dist/lib/custom/Conversations/conversation-overview.panel.js.map +1 -1
- package/dist/lib/custom/Employees/employee-overview.panel.d.ts +1 -1
- package/dist/lib/custom/Employees/employee-overview.panel.js +2 -2
- package/dist/lib/custom/Employees/employee-overview.panel.js.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.d.ts +209 -28
- package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.js +494 -138
- package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
- package/dist/lib/custom/EntityActions/entityaction.form.component.d.ts +5 -1
- package/dist/lib/custom/EntityActions/entityaction.form.component.d.ts.map +1 -1
- package/dist/lib/custom/EntityActions/entityaction.form.component.js +10 -2
- package/dist/lib/custom/EntityActions/entityaction.form.component.js.map +1 -1
- package/dist/lib/custom/Files/file-form.component.d.ts +1 -1
- package/dist/lib/custom/Files/file-form.component.js +2 -2
- package/dist/lib/custom/Files/file-form.component.js.map +1 -1
- package/dist/lib/custom/Lists/list-form.component.d.ts +300 -36
- package/dist/lib/custom/Lists/list-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Lists/list-form.component.js +664 -208
- package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
- package/dist/lib/custom/MLModels/ml-model-view-models.d.ts +31 -0
- package/dist/lib/custom/MLModels/ml-model-view-models.d.ts.map +1 -1
- package/dist/lib/custom/MLModels/ml-model-view-models.js +52 -16
- package/dist/lib/custom/MLModels/ml-model-view-models.js.map +1 -1
- package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts +107 -10
- package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts.map +1 -1
- package/dist/lib/custom/MLModels/ps-model-detail.component.js +291 -101
- package/dist/lib/custom/MLModels/ps-model-detail.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.d.ts +201 -26
- package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.js +429 -109
- package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-run-dialog.component.d.ts +107 -14
- package/dist/lib/custom/Queries/query-run-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/Queries/query-run-dialog.component.js +249 -79
- package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts +110 -4
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts.map +1 -1
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js +858 -86
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js.map +1 -1
- package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts +1 -1
- package/dist/lib/custom/SearchScopes/searchscope-form.component.js +4 -4
- package/dist/lib/custom/SearchScopes/searchscope-form.component.js.map +1 -1
- package/dist/lib/custom/SessionBridges/session-bridge-form.component.js.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.d.ts +77 -13
- package/dist/lib/custom/Templates/template-param-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.js +196 -78
- package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
- package/dist/lib/custom/Templates/template-params-grid.component.d.ts +49 -7
- package/dist/lib/custom/Templates/template-params-grid.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/template-params-grid.component.js +132 -44
- package/dist/lib/custom/Templates/template-params-grid.component.js.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.d.ts +142 -17
- package/dist/lib/custom/Templates/templates-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.js +333 -113
- package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/entity-link-pill.component.d.ts +24 -4
- package/dist/lib/custom/Tests/entity-link-pill.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/entity-link-pill.component.js +64 -20
- package/dist/lib/custom/Tests/entity-link-pill.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.d.ts +217 -27
- package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.js +549 -169
- package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-checks.d.ts +2 -0
- package/dist/lib/custom/Tests/test-run-checks.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-run-checks.js +5 -1
- package/dist/lib/custom/Tests/test-run-checks.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-feedback-form.component.d.ts +2 -0
- package/dist/lib/custom/Tests/test-run-feedback-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-run-feedback-form.component.js +5 -1
- package/dist/lib/custom/Tests/test-run-feedback-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-form.component.d.ts +146 -18
- package/dist/lib/custom/Tests/test-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-run-form.component.js +362 -106
- package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts +390 -47
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.js +1015 -343
- package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts +214 -26
- package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.js +535 -159
- package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
- package/dist/lib/custom/Users/user-overview.panel.d.ts +1 -1
- package/dist/lib/custom/Users/user-overview.panel.js +2 -2
- package/dist/lib/custom/Users/user-overview.panel.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts +208 -29
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +446 -138
- 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-cost.service.d.ts +6 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js +16 -4
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts +50 -6
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js +84 -12
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts +89 -5
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +216 -70
- 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-step-node.component.d.ts +62 -3
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js +140 -42
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts +81 -10
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +165 -37
- 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 +140 -15
- 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 +326 -100
- 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 +101 -15
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js +281 -97
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts +43 -25
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js +100 -64
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts +14 -2
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js +71 -53
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts +14 -2
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js +70 -52
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts +8 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js +22 -6
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts +24 -2
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js +91 -59
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts +10 -2
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js +33 -17
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.d.ts +2 -0
- package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.js +34 -30
- package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts +14 -2
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js +69 -51
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +38 -12
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.js +103 -51
- package/dist/lib/custom/shared/entity-selector-dialog.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 +59 -51
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js +76 -74
- package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJProject/mjproject.form.component.js +27 -25
- package/dist/lib/generated/Entities/MJProject/mjproject.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +155 -119
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts +5 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts.map +1 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js +11 -3
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js.map +1 -1
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.d.ts +2 -0
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.d.ts.map +1 -1
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.js +16 -12
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.js.map +1 -1
- package/dist/lib/panels/content-sources/website-crawler-settings.panel.d.ts +1 -1
- package/dist/lib/panels/content-sources/website-crawler-settings.panel.js +2 -2
- package/dist/lib/panels/content-sources/website-crawler-settings.panel.js.map +1 -1
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +45 -19
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -1
- package/dist/lib/panels/model-predictions/model-prediction.logic.js +95 -43
- package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -1
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts +20 -16
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts.map +1 -1
- package/dist/lib/panels/model-predictions/model-prediction.panel.js +73 -65
- package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -1
- package/dist/lib/shared/components/template-editor.component.d.ts +133 -14
- package/dist/lib/shared/components/template-editor.component.d.ts.map +1 -1
- package/dist/lib/shared/components/template-editor.component.js +322 -124
- package/dist/lib/shared/components/template-editor.component.js.map +1 -1
- package/package.json +43 -42
|
@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms';
|
|
|
4
4
|
import { MJButtonDirective } from '@memberjunction/ng-ui-components';
|
|
5
5
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
6
6
|
import { PredictiveStudioPromoteModelOperation, } from '@memberjunction/core-entities';
|
|
7
|
-
import { PS_FEATURE_DOMINANCE_THRESHOLD,
|
|
7
|
+
import { PS_FEATURE_DOMINANCE_THRESHOLD, FormatMetricValue, HumanizeFeatureName, MaxFeatureImportance, MetricsToDisplay, OverfitGap, ParseFeatureImportance, ParseMetrics, PrimaryModelScore, } from './ml-model-view-models';
|
|
8
8
|
import * as i0 from "@angular/core";
|
|
9
9
|
import * as i1 from "@angular/forms";
|
|
10
10
|
const _forTrack0 = ($index, $item) => $item.key;
|
|
@@ -421,28 +421,104 @@ function PSModelDetailComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
|
421
421
|
*/
|
|
422
422
|
export class PSModelDetailComponent {
|
|
423
423
|
constructor() {
|
|
424
|
-
this.
|
|
425
|
-
this.
|
|
426
|
-
this.
|
|
427
|
-
this.
|
|
428
|
-
this.
|
|
424
|
+
this.Model = null;
|
|
425
|
+
this.Provider = null;
|
|
426
|
+
this.CurrentUser = null;
|
|
427
|
+
this.ShowActions = true;
|
|
428
|
+
this.StatusChanged = new EventEmitter();
|
|
429
|
+
/**
|
|
430
|
+
* @deprecated Use {@link StatusChanged}.
|
|
431
|
+
*
|
|
432
|
+
* The same emitter under the old binding name, so a template still binding
|
|
433
|
+
* (statusChanged) keeps working. Must stay AFTER StatusChanged: class fields
|
|
434
|
+
* initialise in order, and the other way round this captures undefined.
|
|
435
|
+
*/
|
|
436
|
+
this.statusChanged = this.StatusChanged;
|
|
429
437
|
this.cdr = inject(ChangeDetectorRef);
|
|
430
438
|
this.notifications = inject(MJNotificationService);
|
|
431
|
-
this.
|
|
432
|
-
this.
|
|
433
|
-
this.
|
|
434
|
-
this.
|
|
435
|
-
this.
|
|
439
|
+
this.LifecycleSteps = ['Draft', 'Validated', 'Published', 'Archived'];
|
|
440
|
+
this.DominanceThreshold = PS_FEATURE_DOMINANCE_THRESHOLD.toFixed(2);
|
|
441
|
+
this.Pending = null;
|
|
442
|
+
this.PendingReason = '';
|
|
443
|
+
this.Busy = false;
|
|
436
444
|
}
|
|
437
|
-
|
|
445
|
+
/** @deprecated Use {@link Model}. */
|
|
446
|
+
set model(value) {
|
|
447
|
+
this.Model = value;
|
|
448
|
+
}
|
|
449
|
+
/** @deprecated Use {@link Model}. */
|
|
450
|
+
get model() {
|
|
451
|
+
return this.Model;
|
|
452
|
+
}
|
|
453
|
+
/** @deprecated Use {@link Provider}. */
|
|
454
|
+
set provider(value) {
|
|
455
|
+
this.Provider = value;
|
|
456
|
+
}
|
|
457
|
+
/** @deprecated Use {@link Provider}. */
|
|
458
|
+
get provider() {
|
|
459
|
+
return this.Provider;
|
|
460
|
+
}
|
|
461
|
+
/** @deprecated Use {@link CurrentUser}. */
|
|
462
|
+
set currentUser(value) {
|
|
463
|
+
this.CurrentUser = value;
|
|
464
|
+
}
|
|
465
|
+
/** @deprecated Use {@link CurrentUser}. */
|
|
466
|
+
get currentUser() {
|
|
467
|
+
return this.CurrentUser;
|
|
468
|
+
}
|
|
469
|
+
/** @deprecated Use {@link ShowActions}. */
|
|
470
|
+
set showActions(value) {
|
|
471
|
+
this.ShowActions = value;
|
|
472
|
+
}
|
|
473
|
+
/** @deprecated Use {@link ShowActions}. */
|
|
474
|
+
get showActions() {
|
|
475
|
+
return this.ShowActions;
|
|
476
|
+
}
|
|
477
|
+
/** @deprecated Use {@link LifecycleSteps}. */
|
|
478
|
+
get lifecycleSteps() {
|
|
479
|
+
return this.LifecycleSteps;
|
|
480
|
+
}
|
|
481
|
+
/** @deprecated Use {@link DominanceThreshold}. */
|
|
482
|
+
get dominanceThreshold() {
|
|
483
|
+
return this.DominanceThreshold;
|
|
484
|
+
}
|
|
485
|
+
/** @deprecated Use {@link Pending}. */
|
|
486
|
+
get pending() {
|
|
487
|
+
return this.Pending;
|
|
488
|
+
}
|
|
489
|
+
/** @deprecated Use {@link Pending}. */
|
|
490
|
+
set pending(value) {
|
|
491
|
+
this.Pending = value;
|
|
492
|
+
}
|
|
493
|
+
/** @deprecated Use {@link PendingReason}. */
|
|
494
|
+
get pendingReason() {
|
|
495
|
+
return this.PendingReason;
|
|
496
|
+
}
|
|
497
|
+
/** @deprecated Use {@link PendingReason}. */
|
|
498
|
+
set pendingReason(value) {
|
|
499
|
+
this.PendingReason = value;
|
|
500
|
+
}
|
|
501
|
+
/** @deprecated Use {@link Busy}. */
|
|
502
|
+
get busy() {
|
|
503
|
+
return this.Busy;
|
|
504
|
+
}
|
|
505
|
+
/** @deprecated Use {@link Busy}. */
|
|
506
|
+
set busy(value) {
|
|
507
|
+
this.Busy = value;
|
|
508
|
+
}
|
|
509
|
+
get ModelDisplayName() {
|
|
438
510
|
if (this.displayName)
|
|
439
511
|
return this.displayName;
|
|
440
|
-
if (!this.
|
|
512
|
+
if (!this.Model)
|
|
441
513
|
return '';
|
|
442
|
-
return this.
|
|
514
|
+
return this.Model.Pipeline || (this.Model.Algorithm ? `${this.Model.Algorithm} Model` : 'ML Model');
|
|
515
|
+
}
|
|
516
|
+
/** @deprecated Use {@link ModelDisplayName}. */
|
|
517
|
+
get modelDisplayName() {
|
|
518
|
+
return this.ModelDisplayName;
|
|
443
519
|
}
|
|
444
520
|
// ── Badges & Lifecycle Stepper ──
|
|
445
|
-
|
|
521
|
+
StatusBadgeClass(status) {
|
|
446
522
|
switch ((status ?? '').toLowerCase()) {
|
|
447
523
|
case 'published':
|
|
448
524
|
return 'green';
|
|
@@ -456,9 +532,13 @@ export class PSModelDetailComponent {
|
|
|
456
532
|
return 'gray';
|
|
457
533
|
}
|
|
458
534
|
}
|
|
459
|
-
|
|
535
|
+
/** @deprecated Use {@link StatusBadgeClass}. */
|
|
536
|
+
statusBadgeClass(status) {
|
|
537
|
+
return this.StatusBadgeClass(status);
|
|
538
|
+
}
|
|
539
|
+
StepState(step) {
|
|
460
540
|
const order = ['Draft', 'Validated', 'Published', 'Archived'];
|
|
461
|
-
const currIdx = order.indexOf(this.
|
|
541
|
+
const currIdx = order.indexOf(this.Model?.Status ?? 'Draft');
|
|
462
542
|
const stepIdx = order.indexOf(step);
|
|
463
543
|
if (stepIdx < currIdx)
|
|
464
544
|
return 'done';
|
|
@@ -466,97 +546,161 @@ export class PSModelDetailComponent {
|
|
|
466
546
|
return 'curr';
|
|
467
547
|
return 'todo';
|
|
468
548
|
}
|
|
469
|
-
|
|
470
|
-
|
|
549
|
+
/** @deprecated Use {@link StepState}. */
|
|
550
|
+
stepState(step) {
|
|
551
|
+
return this.StepState(step);
|
|
552
|
+
}
|
|
553
|
+
get TargetSuffix() {
|
|
554
|
+
const target = this.Model?.TargetVariable;
|
|
471
555
|
return target ? ` · predicts ${target}` : '';
|
|
472
556
|
}
|
|
557
|
+
/** @deprecated Use {@link TargetSuffix}. */
|
|
558
|
+
get targetSuffix() {
|
|
559
|
+
return this.TargetSuffix;
|
|
560
|
+
}
|
|
473
561
|
// ── Metrics & Performance Derivations ──
|
|
474
|
-
get
|
|
475
|
-
if (!this.
|
|
562
|
+
get PrimaryScoreLabel() {
|
|
563
|
+
if (!this.Model)
|
|
476
564
|
return 'Score';
|
|
477
|
-
const score =
|
|
565
|
+
const score = PrimaryModelScore(this.Model);
|
|
478
566
|
return score?.label ?? 'AUC';
|
|
479
567
|
}
|
|
480
|
-
|
|
481
|
-
|
|
568
|
+
/** @deprecated Use {@link PrimaryScoreLabel}. */
|
|
569
|
+
get primaryScoreLabel() {
|
|
570
|
+
return this.PrimaryScoreLabel;
|
|
571
|
+
}
|
|
572
|
+
get TrainPrimaryScore() {
|
|
573
|
+
if (!this.Model)
|
|
482
574
|
return '—';
|
|
483
|
-
const score =
|
|
484
|
-
const trainMetrics =
|
|
575
|
+
const score = PrimaryModelScore(this.Model);
|
|
576
|
+
const trainMetrics = ParseMetrics(this.Model.Metrics);
|
|
485
577
|
if (score && trainMetrics[score.key] != null) {
|
|
486
|
-
return
|
|
578
|
+
return FormatMetricValue(score.key, trainMetrics[score.key]);
|
|
487
579
|
}
|
|
488
580
|
return trainMetrics.AUC != null ? trainMetrics.AUC.toFixed(3) : '—';
|
|
489
581
|
}
|
|
490
|
-
|
|
491
|
-
|
|
582
|
+
/** @deprecated Use {@link TrainPrimaryScore}. */
|
|
583
|
+
get trainPrimaryScore() {
|
|
584
|
+
return this.TrainPrimaryScore;
|
|
585
|
+
}
|
|
586
|
+
get HoldoutPrimaryScore() {
|
|
587
|
+
if (!this.Model)
|
|
492
588
|
return '—';
|
|
493
|
-
const score =
|
|
494
|
-
const holdoutMetrics =
|
|
589
|
+
const score = PrimaryModelScore(this.Model);
|
|
590
|
+
const holdoutMetrics = ParseMetrics(this.Model.HoldoutMetrics);
|
|
495
591
|
if (score && holdoutMetrics[score.key] != null) {
|
|
496
|
-
return
|
|
592
|
+
return FormatMetricValue(score.key, holdoutMetrics[score.key]);
|
|
497
593
|
}
|
|
498
594
|
return holdoutMetrics.AUC != null ? holdoutMetrics.AUC.toFixed(3) : '—';
|
|
499
595
|
}
|
|
500
|
-
|
|
501
|
-
|
|
596
|
+
/** @deprecated Use {@link HoldoutPrimaryScore}. */
|
|
597
|
+
get holdoutPrimaryScore() {
|
|
598
|
+
return this.HoldoutPrimaryScore;
|
|
599
|
+
}
|
|
600
|
+
get SecondaryMetrics() {
|
|
601
|
+
if (!this.Model)
|
|
502
602
|
return [];
|
|
503
|
-
const score =
|
|
603
|
+
const score = PrimaryModelScore(this.Model);
|
|
504
604
|
const primaryKey = score?.key;
|
|
505
|
-
const holdout =
|
|
506
|
-
const all = holdout.length > 0 ? holdout :
|
|
605
|
+
const holdout = MetricsToDisplay(ParseMetrics(this.Model.HoldoutMetrics), { excludeAuc: false });
|
|
606
|
+
const all = holdout.length > 0 ? holdout : MetricsToDisplay(ParseMetrics(this.Model.Metrics), { excludeAuc: false });
|
|
507
607
|
return primaryKey ? all.filter((m) => m.key !== primaryKey) : all.filter((m) => m.key !== 'AUC');
|
|
508
608
|
}
|
|
509
|
-
|
|
510
|
-
|
|
609
|
+
/** @deprecated Use {@link SecondaryMetrics}. */
|
|
610
|
+
get secondaryMetrics() {
|
|
611
|
+
return this.SecondaryMetrics;
|
|
612
|
+
}
|
|
613
|
+
get GapText() {
|
|
614
|
+
if (!this.Model)
|
|
511
615
|
return '';
|
|
512
|
-
const gap =
|
|
616
|
+
const gap = OverfitGap(this.Model);
|
|
513
617
|
return gap == null ? '' : Math.abs(gap).toFixed(3);
|
|
514
618
|
}
|
|
515
|
-
|
|
516
|
-
|
|
619
|
+
/** @deprecated Use {@link GapText}. */
|
|
620
|
+
get gapText() {
|
|
621
|
+
return this.GapText;
|
|
622
|
+
}
|
|
623
|
+
get GapVerdict() {
|
|
624
|
+
if (!this.Model)
|
|
517
625
|
return '';
|
|
518
|
-
const gap =
|
|
626
|
+
const gap = OverfitGap(this.Model);
|
|
519
627
|
if (gap == null)
|
|
520
628
|
return '';
|
|
521
629
|
return gap > 0.1 ? 'is wide — watch for overfitting' : 'is within tolerance — no overfitting flag';
|
|
522
630
|
}
|
|
631
|
+
/** @deprecated Use {@link GapVerdict}. */
|
|
632
|
+
get gapVerdict() {
|
|
633
|
+
return this.GapVerdict;
|
|
634
|
+
}
|
|
523
635
|
// ── Feature Importance & Leakage Gate ──
|
|
524
|
-
get
|
|
525
|
-
if (!this.
|
|
636
|
+
get Importance() {
|
|
637
|
+
if (!this.Model)
|
|
526
638
|
return [];
|
|
527
|
-
return
|
|
639
|
+
return ParseFeatureImportance(this.Model.FeatureImportance, 6).map((b) => ({
|
|
528
640
|
...b,
|
|
529
|
-
name:
|
|
641
|
+
name: HumanizeFeatureName(b.name),
|
|
530
642
|
}));
|
|
531
643
|
}
|
|
532
|
-
|
|
533
|
-
|
|
644
|
+
/** @deprecated Use {@link Importance}. */
|
|
645
|
+
get importance() {
|
|
646
|
+
return this.Importance;
|
|
647
|
+
}
|
|
648
|
+
get ImportanceCaption() {
|
|
649
|
+
const n = this.Importance.length;
|
|
534
650
|
return n === 0 ? 'no data' : `normalized · top ${n}`;
|
|
535
651
|
}
|
|
652
|
+
/** @deprecated Use {@link ImportanceCaption}. */
|
|
653
|
+
get importanceCaption() {
|
|
654
|
+
return this.ImportanceCaption;
|
|
655
|
+
}
|
|
656
|
+
get TopFeatureName() {
|
|
657
|
+
return this.Importance[0]?.name ?? '—';
|
|
658
|
+
}
|
|
659
|
+
/** @deprecated Use {@link TopFeatureName}. */
|
|
536
660
|
get topFeatureName() {
|
|
537
|
-
return this.
|
|
661
|
+
return this.TopFeatureName;
|
|
662
|
+
}
|
|
663
|
+
get TopFeatureValue() {
|
|
664
|
+
return this.Importance[0]?.value ?? '—';
|
|
538
665
|
}
|
|
666
|
+
/** @deprecated Use {@link TopFeatureValue}. */
|
|
539
667
|
get topFeatureValue() {
|
|
540
|
-
return this.
|
|
668
|
+
return this.TopFeatureValue;
|
|
541
669
|
}
|
|
542
|
-
get
|
|
543
|
-
if (!this.
|
|
670
|
+
get LeakageFlagged() {
|
|
671
|
+
if (!this.Model)
|
|
544
672
|
return false;
|
|
545
|
-
const max =
|
|
673
|
+
const max = MaxFeatureImportance(this.Model.FeatureImportance);
|
|
546
674
|
return max != null && max >= PS_FEATURE_DOMINANCE_THRESHOLD;
|
|
547
675
|
}
|
|
676
|
+
/** @deprecated Use {@link LeakageFlagged}. */
|
|
677
|
+
get leakageFlagged() {
|
|
678
|
+
return this.LeakageFlagged;
|
|
679
|
+
}
|
|
548
680
|
// ── Actions & Promotion Flow ──
|
|
681
|
+
get CanValidate() {
|
|
682
|
+
return this.Model?.Status === 'Draft';
|
|
683
|
+
}
|
|
684
|
+
/** @deprecated Use {@link CanValidate}. */
|
|
549
685
|
get canValidate() {
|
|
550
|
-
return this.
|
|
686
|
+
return this.CanValidate;
|
|
551
687
|
}
|
|
688
|
+
get CanPublish() {
|
|
689
|
+
return this.Model?.Status === 'Validated';
|
|
690
|
+
}
|
|
691
|
+
/** @deprecated Use {@link CanPublish}. */
|
|
552
692
|
get canPublish() {
|
|
553
|
-
return this.
|
|
693
|
+
return this.CanPublish;
|
|
694
|
+
}
|
|
695
|
+
get CanArchive() {
|
|
696
|
+
return this.Model?.Status === 'Published' || this.Model?.Status === 'Validated';
|
|
554
697
|
}
|
|
698
|
+
/** @deprecated Use {@link CanArchive}. */
|
|
555
699
|
get canArchive() {
|
|
556
|
-
return this.
|
|
700
|
+
return this.CanArchive;
|
|
557
701
|
}
|
|
558
|
-
get
|
|
559
|
-
switch (this.
|
|
702
|
+
get ActionHint() {
|
|
703
|
+
switch (this.Model?.Status) {
|
|
560
704
|
case 'Draft':
|
|
561
705
|
return 'Verify metrics and feature importance before validating or publishing.';
|
|
562
706
|
case 'Validated':
|
|
@@ -569,65 +713,97 @@ export class PSModelDetailComponent {
|
|
|
569
713
|
return '';
|
|
570
714
|
}
|
|
571
715
|
}
|
|
572
|
-
|
|
573
|
-
|
|
716
|
+
/** @deprecated Use {@link ActionHint}. */
|
|
717
|
+
get actionHint() {
|
|
718
|
+
return this.ActionHint;
|
|
719
|
+
}
|
|
720
|
+
RequestPromote(targetStatus) {
|
|
721
|
+
if (!this.Model)
|
|
574
722
|
return;
|
|
575
|
-
this.
|
|
576
|
-
this.
|
|
577
|
-
modelId: this.
|
|
578
|
-
modelName: `${this.
|
|
723
|
+
this.PendingReason = '';
|
|
724
|
+
this.Pending = {
|
|
725
|
+
modelId: this.Model.ID,
|
|
726
|
+
modelName: `${this.ModelDisplayName} v${this.Model.Version}`,
|
|
579
727
|
targetStatus,
|
|
580
|
-
leakageFlagged: this.
|
|
728
|
+
leakageFlagged: this.LeakageFlagged && targetStatus !== 'Archived',
|
|
581
729
|
};
|
|
582
730
|
this.cdr.markForCheck();
|
|
583
731
|
}
|
|
584
|
-
|
|
585
|
-
|
|
732
|
+
/** @deprecated Use {@link RequestPromote}. */
|
|
733
|
+
requestPromote(targetStatus) {
|
|
734
|
+
return this.RequestPromote(targetStatus);
|
|
735
|
+
}
|
|
736
|
+
CancelPromote() {
|
|
737
|
+
if (this.Busy)
|
|
586
738
|
return;
|
|
587
|
-
this.
|
|
588
|
-
this.
|
|
739
|
+
this.Pending = null;
|
|
740
|
+
this.PendingReason = '';
|
|
589
741
|
this.cdr.markForCheck();
|
|
590
742
|
}
|
|
591
|
-
|
|
592
|
-
|
|
743
|
+
/** @deprecated Use {@link CancelPromote}. */
|
|
744
|
+
cancelPromote() {
|
|
745
|
+
return this.CancelPromote();
|
|
746
|
+
}
|
|
747
|
+
get PendingTitle() {
|
|
748
|
+
if (!this.Pending)
|
|
593
749
|
return '';
|
|
594
|
-
return this.
|
|
750
|
+
return this.Pending.targetStatus === 'Archived' ? 'Archive model' : `Promote to ${this.Pending.targetStatus}`;
|
|
595
751
|
}
|
|
596
|
-
|
|
597
|
-
|
|
752
|
+
/** @deprecated Use {@link PendingTitle}. */
|
|
753
|
+
get pendingTitle() {
|
|
754
|
+
return this.PendingTitle;
|
|
755
|
+
}
|
|
756
|
+
get PendingIcon() {
|
|
757
|
+
if (!this.Pending)
|
|
598
758
|
return 'fa-solid fa-check';
|
|
599
|
-
return this.
|
|
759
|
+
return this.Pending.targetStatus === 'Archived' ? 'fa-solid fa-box-archive' : 'fa-solid fa-arrow-up';
|
|
600
760
|
}
|
|
601
|
-
|
|
602
|
-
|
|
761
|
+
/** @deprecated Use {@link PendingIcon}. */
|
|
762
|
+
get pendingIcon() {
|
|
763
|
+
return this.PendingIcon;
|
|
764
|
+
}
|
|
765
|
+
get PendingConfirmLabel() {
|
|
766
|
+
if (!this.Pending)
|
|
603
767
|
return 'Confirm';
|
|
604
|
-
return this.
|
|
768
|
+
return this.Pending.targetStatus === 'Archived' ? 'Archive' : `Promote to ${this.Pending.targetStatus}`;
|
|
605
769
|
}
|
|
606
|
-
|
|
607
|
-
|
|
770
|
+
/** @deprecated Use {@link PendingConfirmLabel}. */
|
|
771
|
+
get pendingConfirmLabel() {
|
|
772
|
+
return this.PendingConfirmLabel;
|
|
773
|
+
}
|
|
774
|
+
get PendingVariant() {
|
|
775
|
+
if (!this.Pending)
|
|
608
776
|
return 'info';
|
|
609
|
-
if (this.
|
|
777
|
+
if (this.Pending.targetStatus === 'Archived')
|
|
610
778
|
return 'warn';
|
|
611
|
-
return this.
|
|
779
|
+
return this.Pending.leakageFlagged ? 'warn' : 'info';
|
|
612
780
|
}
|
|
613
|
-
|
|
614
|
-
|
|
781
|
+
/** @deprecated Use {@link PendingVariant}. */
|
|
782
|
+
get pendingVariant() {
|
|
783
|
+
return this.PendingVariant;
|
|
784
|
+
}
|
|
785
|
+
get PendingMessage() {
|
|
786
|
+
if (!this.Pending)
|
|
615
787
|
return '';
|
|
616
|
-
const name = this.escapeHtml(this.
|
|
617
|
-
if (this.
|
|
788
|
+
const name = this.escapeHtml(this.Pending.modelName);
|
|
789
|
+
if (this.Pending.targetStatus === 'Archived') {
|
|
618
790
|
return `Archive <strong>${name}</strong>? This detaches any active scoring bindings and removes it from production scoring. The model artifact remains immutable and recoverable.`;
|
|
619
791
|
}
|
|
620
|
-
if (this.
|
|
792
|
+
if (this.Pending.leakageFlagged) {
|
|
621
793
|
return `<strong>${name}</strong> is flagged for possible target leakage. Publishing requires an explicit sign-off — confirm you understand the risk and provide a reason below.`;
|
|
622
794
|
}
|
|
623
|
-
return `Promote <strong>${name}</strong> to <strong>${this.
|
|
795
|
+
return `Promote <strong>${name}</strong> to <strong>${this.Pending.targetStatus}</strong>? This changes only the lifecycle state — the trained weights never change.`;
|
|
624
796
|
}
|
|
625
|
-
|
|
626
|
-
|
|
797
|
+
/** @deprecated Use {@link PendingMessage}. */
|
|
798
|
+
get pendingMessage() {
|
|
799
|
+
return this.PendingMessage;
|
|
800
|
+
}
|
|
801
|
+
async ConfirmPromote(reason) {
|
|
802
|
+
if (!this.Pending || this.Busy || !this.Model)
|
|
627
803
|
return;
|
|
628
|
-
this.
|
|
804
|
+
this.Busy = true;
|
|
629
805
|
this.cdr.markForCheck();
|
|
630
|
-
const { modelId, modelName, targetStatus, leakageFlagged } = this.
|
|
806
|
+
const { modelId, modelName, targetStatus, leakageFlagged } = this.Pending;
|
|
631
807
|
try {
|
|
632
808
|
const op = new PredictiveStudioPromoteModelOperation();
|
|
633
809
|
const result = await op.Execute({
|
|
@@ -635,14 +811,14 @@ export class PSModelDetailComponent {
|
|
|
635
811
|
targetStatus,
|
|
636
812
|
signOff: leakageFlagged ? true : undefined,
|
|
637
813
|
reason: reason || undefined,
|
|
638
|
-
}, { provider: this.
|
|
814
|
+
}, { provider: this.Provider ?? undefined, user: this.CurrentUser ?? undefined });
|
|
639
815
|
if (result.Success && result.Output?.promoted) {
|
|
640
816
|
const newStatus = result.Output.status;
|
|
641
|
-
this.
|
|
817
|
+
this.Model.Status = newStatus;
|
|
642
818
|
this.notifications.CreateSimpleNotification(`${modelName} → ${newStatus}`, 'success', 3500);
|
|
643
|
-
this.
|
|
644
|
-
this.
|
|
645
|
-
this.
|
|
819
|
+
this.StatusChanged.emit({ modelId, newStatus });
|
|
820
|
+
this.Pending = null;
|
|
821
|
+
this.PendingReason = '';
|
|
646
822
|
}
|
|
647
823
|
else {
|
|
648
824
|
this.notifications.CreateSimpleNotification(result.ErrorMessage || `Could not promote ${modelName} (status: ${result.Output?.status ?? 'unchanged'}).`, 'error', 5000);
|
|
@@ -652,10 +828,14 @@ export class PSModelDetailComponent {
|
|
|
652
828
|
this.notifications.CreateSimpleNotification(`Promotion failed: ${e instanceof Error ? e.message : String(e)}`, 'error', 5000);
|
|
653
829
|
}
|
|
654
830
|
finally {
|
|
655
|
-
this.
|
|
831
|
+
this.Busy = false;
|
|
656
832
|
this.cdr.markForCheck();
|
|
657
833
|
}
|
|
658
834
|
}
|
|
835
|
+
/** @deprecated Use {@link ConfirmPromote}. */
|
|
836
|
+
async confirmPromote(reason) {
|
|
837
|
+
return this.ConfirmPromote(reason);
|
|
838
|
+
}
|
|
659
839
|
escapeHtml(value) {
|
|
660
840
|
return value
|
|
661
841
|
.replace(/&/g, '&')
|
|
@@ -664,7 +844,7 @@ export class PSModelDetailComponent {
|
|
|
664
844
|
.replace(/"/g, '"');
|
|
665
845
|
}
|
|
666
846
|
static { this.ɵfac = function PSModelDetailComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PSModelDetailComponent)(); }; }
|
|
667
|
-
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PSModelDetailComponent, selectors: [["ps-model-detail"]], inputs: { model: "model", provider: "provider", currentUser: "currentUser", showActions: "showActions", displayName: "displayName" }, outputs: { statusChanged: "statusChanged" }, decls: 3, vars: 1, consts: [["data-testid", "ps-model-detail", 1, "ps-model-detail"], [1, "ps-empty", 2, "padding", "32px", "text-align", "center"], [1, "ps-card"], [1, "ps-card-body", "dh"], [1, "big-ico"], [1, "fa-solid", "fa-cube"], [2, "flex", "1", "min-width", "0"], ["data-testid", "ps-registry-detail-name"], [1, "ps-tag", "ps-mono"], [1, "ps-muted", "ps-small", "sub"], [1, "ps-badge"], [1, "ps-card-body"], [1, "ps-section-title"], [1, "ps-stepper"], [1, "ps-small", "ps-muted", 2, "margin-top", "10px"], [1, "ps-card-head"], [1, "ps-muted", "ps-small"], [1, "metric-pair"], [1, "mtile"], [1, "v"], [1, "mtile", "honest"], [1, "stat-bar"], [1, "ps-small", "ps-muted", 2, "margin-top", "6px"], [1, "ps-small", "ps-muted"], [1, "ps-callout", "gate", 3, "success", "warn"], [1, "ps-modal-backdrop"], [1, "ps-step"], [1, "pip"], [1, "fa-solid", "fa-check"], [1, "ln"], [1, "b"], [1, "ps-fbar"], [1, "name", "ps-small", 3, "title"], [1, "track"], [1, "ps-mono"], [1, "ps-callout", "gate"], [1, "ps-small", 2, "margin-top", "6px"], [1, "fa-solid", "fa-pen"], [1, "ps-card-body", "ps-row", 2, "align-items", "center", "flex-wrap", "wrap", "gap", "8px"], [1, "ps-muted", "ps-small", 2, "flex", "1"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-registry-validate"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-registry-promote"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-registry-archive"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-registry-validate", 3, "click"], [1, "fa-solid", "fa-circle-check"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-registry-promote", 3, "click"], [1, "fa-solid", "fa-arrow-up"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-registry-archive", 3, "click"], [1, "fa-solid", "fa-box-archive"], [1, "ps-modal-backdrop", 3, "click"], ["data-testid", "ps-confirm-modal", 1, "ps-modal", 3, "click"], [1, "ps-modal-head"], [1, "ico"], [1, "ps-modal-body"], [3, "innerHTML"], [1, "ps-field", 2, "margin-top", "12px"], [1, "ps-modal-foot"], ["mjButton", "", "size", "sm", 3, "click", "variant", "disabled"], [1, "fa-solid", "fa-circle-notch", "fa-spin"], [3, "class"], [1, "ps-spacer", 2, "flex", "1"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], ["rows", "3", 1, "ps-input", 3, "ngModelChange", "ngModel", "placeholder", "disabled"], [1, "ps-empty-ico"], [1, "ps-muted"]], template: function PSModelDetailComponent_Template(rf, ctx) { if (rf & 1) {
|
|
847
|
+
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PSModelDetailComponent, selectors: [["ps-model-detail"]], inputs: { Model: "Model", model: "model", Provider: "Provider", provider: "provider", CurrentUser: "CurrentUser", currentUser: "currentUser", ShowActions: "ShowActions", showActions: "showActions", displayName: "displayName" }, outputs: { StatusChanged: "StatusChanged", statusChanged: "statusChanged" }, decls: 3, vars: 1, consts: [["data-testid", "ps-model-detail", 1, "ps-model-detail"], [1, "ps-empty", 2, "padding", "32px", "text-align", "center"], [1, "ps-card"], [1, "ps-card-body", "dh"], [1, "big-ico"], [1, "fa-solid", "fa-cube"], [2, "flex", "1", "min-width", "0"], ["data-testid", "ps-registry-detail-name"], [1, "ps-tag", "ps-mono"], [1, "ps-muted", "ps-small", "sub"], [1, "ps-badge"], [1, "ps-card-body"], [1, "ps-section-title"], [1, "ps-stepper"], [1, "ps-small", "ps-muted", 2, "margin-top", "10px"], [1, "ps-card-head"], [1, "ps-muted", "ps-small"], [1, "metric-pair"], [1, "mtile"], [1, "v"], [1, "mtile", "honest"], [1, "stat-bar"], [1, "ps-small", "ps-muted", 2, "margin-top", "6px"], [1, "ps-small", "ps-muted"], [1, "ps-callout", "gate", 3, "success", "warn"], [1, "ps-modal-backdrop"], [1, "ps-step"], [1, "pip"], [1, "fa-solid", "fa-check"], [1, "ln"], [1, "b"], [1, "ps-fbar"], [1, "name", "ps-small", 3, "title"], [1, "track"], [1, "ps-mono"], [1, "ps-callout", "gate"], [1, "ps-small", 2, "margin-top", "6px"], [1, "fa-solid", "fa-pen"], [1, "ps-card-body", "ps-row", 2, "align-items", "center", "flex-wrap", "wrap", "gap", "8px"], [1, "ps-muted", "ps-small", 2, "flex", "1"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-registry-validate"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-registry-promote"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-registry-archive"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-registry-validate", 3, "click"], [1, "fa-solid", "fa-circle-check"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-registry-promote", 3, "click"], [1, "fa-solid", "fa-arrow-up"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-registry-archive", 3, "click"], [1, "fa-solid", "fa-box-archive"], [1, "ps-modal-backdrop", 3, "click"], ["data-testid", "ps-confirm-modal", 1, "ps-modal", 3, "click"], [1, "ps-modal-head"], [1, "ico"], [1, "ps-modal-body"], [3, "innerHTML"], [1, "ps-field", 2, "margin-top", "12px"], [1, "ps-modal-foot"], ["mjButton", "", "size", "sm", 3, "click", "variant", "disabled"], [1, "fa-solid", "fa-circle-notch", "fa-spin"], [3, "class"], [1, "ps-spacer", 2, "flex", "1"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], ["rows", "3", 1, "ps-input", 3, "ngModelChange", "ngModel", "placeholder", "disabled"], [1, "ps-empty-ico"], [1, "ps-muted"]], template: function PSModelDetailComponent_Template(rf, ctx) { if (rf & 1) {
|
|
668
848
|
i0.ɵɵelementStart(0, "div", 0);
|
|
669
849
|
i0.ɵɵconditionalCreate(1, PSModelDetailComponent_Conditional_1_Template, 59, 18)(2, PSModelDetailComponent_Conditional_2_Template, 7, 0, "div", 1);
|
|
670
850
|
i0.ɵɵelementEnd();
|
|
@@ -676,14 +856,24 @@ export class PSModelDetailComponent {
|
|
|
676
856
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PSModelDetailComponent, [{
|
|
677
857
|
type: Component,
|
|
678
858
|
args: [{ standalone: true, selector: 'ps-model-detail', imports: [CommonModule, FormsModule, MJButtonDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ps-model-detail\" data-testid=\"ps-model-detail\">\n @if (model) {\n <!-- 1. Header Card -->\n <div class=\"ps-card\">\n <div class=\"ps-card-body dh\">\n <div class=\"big-ico\"><i class=\"fa-solid fa-cube\"></i></div>\n <div style=\"flex:1;min-width:0;\">\n <h2 data-testid=\"ps-registry-detail-name\">\n {{ modelDisplayName }}\n <span class=\"ps-tag ps-mono\">v{{ model.Version }}</span>\n </h2>\n <div class=\"ps-muted ps-small sub\">\n {{ model.Algorithm || 'Model' }}{{ targetSuffix }} • immutable snapshot\n </div>\n </div>\n <span class=\"ps-badge\" [class]=\"statusBadgeClass(model.Status)\">{{ model.Status }}</span>\n </div>\n </div>\n\n <!-- 2. Lifecycle Stepper -->\n <div class=\"ps-card\">\n <div class=\"ps-card-body\">\n <div class=\"ps-section-title\">Lifecycle</div>\n <div class=\"ps-stepper\">\n @for (step of lifecycleSteps; track step; let last = $last) {\n <div class=\"ps-step\" [class.done]=\"stepState(step) === 'done'\" [class.curr]=\"stepState(step) === 'curr'\">\n <span class=\"pip\">\n @if (stepState(step) === 'done') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n {{ $index + 1 }}\n }\n </span>\n {{ step }}\n </div>\n @if (!last) {\n <span class=\"ln\"></span>\n }\n }\n </div>\n <div class=\"ps-small ps-muted\" style=\"margin-top:10px\">\n Models are immutable once registered; promotion only changes lifecycle state, never weights.\n </div>\n </div>\n </div>\n\n <!-- 3. Performance Metrics -->\n <div class=\"ps-card\">\n <div class=\"ps-card-head\">\n <h3>Performance</h3>\n <span class=\"ps-muted ps-small\">Holdout = held-out test fold, never seen in training</span>\n </div>\n <div class=\"ps-card-body\">\n <div class=\"metric-pair\">\n <div class=\"mtile\">\n <div class=\"ps-section-title\">Train {{ primaryScoreLabel }}</div>\n <div class=\"v\">{{ trainPrimaryScore }}</div>\n <div class=\"ps-muted ps-small\">in-sample • optimistic</div>\n </div>\n <div class=\"mtile honest\">\n <div class=\"ps-section-title\">Holdout {{ primaryScoreLabel }}</div>\n <div class=\"v\">{{ holdoutPrimaryScore }}</div>\n <div class=\"ps-muted ps-small\">out-of-sample • the honest number</div>\n </div>\n </div>\n\n @if (secondaryMetrics.length > 0) {\n <div class=\"stat-bar\">\n @for (s of secondaryMetrics; track s.key) {\n <div class=\"b\">\n <span class=\"ps-muted ps-small\">{{ s.label }}</span>\n <strong>{{ s.value }}</strong>\n </div>\n }\n </div>\n } @else {\n <div class=\"ps-small ps-muted\" style=\"margin-top:6px\">No secondary metrics recorded for this model.</div>\n }\n\n @if (gapText) {\n <div class=\"ps-small ps-muted\" style=\"margin-top:10px\">\n Train\u2013holdout gap of <strong>{{ gapText }}</strong> {{ gapVerdict }}.\n </div>\n }\n </div>\n </div>\n\n <!-- 4. Feature Importance -->\n <div class=\"ps-card\">\n <div class=\"ps-card-head\">\n <h3>Feature Importance</h3>\n <span class=\"ps-muted ps-small\">{{ importanceCaption }}</span>\n </div>\n <div class=\"ps-card-body\">\n @if (importance.length > 0) {\n @for (f of importance; track f.name) {\n <div class=\"ps-fbar\">\n <span class=\"name ps-small\" [title]=\"f.name\">{{ f.name }}</span>\n <div class=\"track\">\n <span [class.warn]=\"f.warning\" [style.width.%]=\"f.pct\"></span>\n </div>\n <span class=\"ps-mono\">{{ f.value }}</span>\n </div>\n }\n } @else {\n <div class=\"ps-small ps-muted\">No feature-importance data was recorded for this model.</div>\n }\n </div>\n </div>\n\n <!-- 5. Leakage Sign-Off Gate -->\n @if (importance.length > 0) {\n <div class=\"ps-callout gate\" [class.success]=\"!leakageFlagged\" [class.warn]=\"leakageFlagged\">\n <i [class]=\"leakageFlagged ? 'fa-solid fa-triangle-exclamation' : 'fa-solid fa-shield-halved'\"></i>\n <div>\n @if (leakageFlagged) {\n <strong>Leakage flag raised.</strong> A single feature dominates \u2014 top importance is\n <strong>{{ topFeatureName }} at {{ topFeatureValue }}</strong>, at/above the\n <strong>{{ dominanceThreshold }}</strong> dominance threshold.\n <div class=\"ps-small\" style=\"margin-top:6px\">\n <i class=\"fa-solid fa-pen\"></i> Sign-off with a reason is required to publish this model.\n </div>\n } @else {\n <strong>Leakage gate clear.</strong> No single feature dominates \u2014 top importance is\n <strong>{{ topFeatureName }} at {{ topFeatureValue }}</strong>, below the\n <strong>{{ dominanceThreshold }}</strong> dominance threshold.\n <div class=\"ps-small\" style=\"margin-top:6px\">\n <i class=\"fa-solid fa-check\"></i> Sign-off required before any Validated → Published promotion.\n </div>\n }\n </div>\n </div>\n }\n\n <!-- 6. Lifecycle Actions -->\n @if (showActions) {\n <div class=\"ps-card\">\n <div class=\"ps-card-body ps-row\" style=\"align-items:center;flex-wrap:wrap;gap:8px\">\n <span class=\"ps-muted ps-small\" style=\"flex:1\">{{ actionHint }}</span>\n @if (canValidate) {\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-registry-validate\" (click)=\"requestPromote('Validated')\">\n <i class=\"fa-solid fa-circle-check\"></i> Mark Validated\n </button>\n }\n @if (canPublish) {\n <button mjButton variant=\"primary\" size=\"sm\" data-testid=\"ps-registry-promote\" (click)=\"requestPromote('Published')\">\n <i class=\"fa-solid fa-arrow-up\"></i> Promote to Published\n </button>\n }\n @if (canArchive) {\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-registry-archive\" (click)=\"requestPromote('Archived')\">\n <i class=\"fa-solid fa-box-archive\"></i> Archive\n </button>\n }\n </div>\n </div>\n }\n\n <!-- 7. Confirm Promotion Modal -->\n @if (pending) {\n <div class=\"ps-modal-backdrop\" (click)=\"cancelPromote()\">\n <div class=\"ps-modal\" (click)=\"$event.stopPropagation()\" data-testid=\"ps-confirm-modal\">\n <div class=\"ps-modal-head\" [class.warn]=\"pendingVariant === 'warn'\" [class.danger]=\"pendingVariant === 'danger'\">\n <span class=\"ico\"><i [class]=\"pendingIcon\"></i></span>\n <h3>{{ pendingTitle }}</h3>\n </div>\n <div class=\"ps-modal-body\">\n <div [innerHTML]=\"pendingMessage\"></div>\n @if (pending.leakageFlagged || pending.targetStatus === 'Archived') {\n <div class=\"ps-field\" style=\"margin-top:12px\">\n <label>\n {{ pending.leakageFlagged ? 'Leakage sign-off reason' : 'Reason (optional)' }}\n {{ pending.leakageFlagged ? ' *' : '' }}\n </label>\n <textarea\n class=\"ps-input\"\n rows=\"3\"\n [(ngModel)]=\"pendingReason\"\n [placeholder]=\"pending.leakageFlagged ? 'Explain why this model is safe to publish despite the leakage flag\u2026' : 'Add an optional note for the record\u2026'\"\n [disabled]=\"busy\"></textarea>\n </div>\n }\n </div>\n <div class=\"ps-modal-foot\">\n <button\n mjButton\n [variant]=\"pendingVariant === 'danger' ? 'danger' : 'primary'\"\n size=\"sm\"\n [disabled]=\"busy || (pending.leakageFlagged && !pendingReason.trim())\"\n (click)=\"confirmPromote(pendingReason.trim())\">\n @if (busy) {\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n } @else {\n <i [class]=\"pendingIcon\"></i>\n }\n {{ pendingConfirmLabel }}\n </button>\n <span class=\"ps-spacer\" style=\"flex:1\"></span>\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"busy\" (click)=\"cancelPromote()\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n } @else {\n <div class=\"ps-empty\" style=\"padding: 32px; text-align: center;\">\n <span class=\"ps-empty-ico\"><i class=\"fa-solid fa-cube\"></i></span>\n <h3>No Model Selected</h3>\n <p class=\"ps-muted\">Select an ML Model from the list to inspect its configuration and metrics.</p>\n </div>\n }\n</div>\n", styles: ["/* PSModelDetailComponent Styles \u2014 Design Token Compliant */\n\n.ps-model-detail {\n display: flex;\n flex-direction: column;\n gap: 16px;\n width: 100%;\n color: var(--mj-text-primary);\n background: transparent;\n font-family: inherit;\n}\n\n/* ---- generic helpers ---- */\n.ps-model-detail .ps-row { display: flex; gap: 16px; }\n.ps-model-detail .ps-col { display: flex; flex-direction: column; gap: 16px; }\n.ps-model-detail .ps-spacer { flex: 1; }\n.ps-model-detail .ps-muted { color: var(--mj-text-muted); }\n.ps-model-detail .ps-small { font-size: 12.5px; }\n.ps-model-detail .ps-mono { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 12.5px; }\n.ps-model-detail .ps-section-title {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: .06em;\n color: var(--mj-text-muted);\n margin: 4px 0 2px;\n font-weight: 700;\n}\n\n/* ---- cards ---- */\n.ps-model-detail .ps-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n.ps-model-detail .ps-card-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n}\n.ps-model-detail .ps-card-head h3 {\n font-size: 14.5px;\n margin: 0;\n font-weight: 650;\n color: var(--mj-text-primary);\n}\n.ps-model-detail .ps-card-body {\n padding: 16px;\n}\n\n/* ---- badges & tags ---- */\n.ps-model-detail .ps-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 10px;\n border-radius: 999px;\n font-size: 11.5px;\n font-weight: 650;\n line-height: 1.5;\n}\n.ps-model-detail .ps-badge.gray { background: var(--mj-bg-surface-sunken, #f3f4f6); color: var(--mj-text-secondary); }\n.ps-model-detail .ps-badge.blue { background: var(--mj-status-info-bg, #eff6ff); color: var(--mj-status-info-text, #1d4ed8); }\n.ps-model-detail .ps-badge.green { background: var(--mj-status-success-bg, #f0fdf4); color: var(--mj-status-success-text, #15803d); }\n.ps-model-detail .ps-badge.amber { background: var(--mj-status-warning-bg, #fffbeb); color: var(--mj-status-warning-text, #b45309); }\n.ps-model-detail .ps-badge.red { background: var(--mj-status-error-bg, #fef2f2); color: var(--mj-status-error-text, #b91c1c); }\n\n.ps-model-detail .ps-tag {\n display: inline-flex;\n align-items: center;\n padding: 2px 7px;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 600;\n background: var(--mj-bg-surface-sunken, #f3f4f6);\n color: var(--mj-text-secondary);\n}\n\n/* ---- detail header ---- */\n.ps-model-detail .dh {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n.ps-model-detail .big-ico {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: grid;\n place-items: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 20px;\n flex: 0 0 auto;\n}\n.ps-model-detail .dh h2 {\n font-size: 18px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n font-weight: 700;\n}\n.ps-model-detail .dh .sub {\n margin-top: 2px;\n}\n\n/* ---- stepper ---- */\n.ps-model-detail .ps-stepper {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n.ps-model-detail .ps-step {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-muted);\n}\n.ps-model-detail .ps-step.curr {\n color: var(--mj-text-primary);\n}\n.ps-model-detail .ps-step.done {\n color: var(--mj-status-success, #15803d);\n}\n.ps-model-detail .ps-step .pip {\n width: 22px;\n height: 22px;\n border-radius: 50%;\n display: grid;\n place-items: center;\n font-size: 11px;\n border: 1.5px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n.ps-model-detail .ps-step.curr .pip {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 700;\n}\n.ps-model-detail .ps-step.done .pip {\n background: var(--mj-status-success, #15803d);\n border-color: var(--mj-status-success, #15803d);\n color: var(--mj-text-inverse);\n}\n.ps-model-detail .ps-stepper .ln {\n flex: 1;\n min-width: 16px;\n height: 2px;\n background: var(--mj-border-default);\n}\n\n/* ---- performance metrics ---- */\n.ps-model-detail .metric-pair {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n}\n@media (max-width: 640px) {\n .ps-model-detail .metric-pair {\n grid-template-columns: 1fr;\n }\n}\n.ps-model-detail .mtile {\n border: 1px solid var(--mj-border-default);\n border-radius: 9px;\n padding: 14px;\n background: var(--mj-bg-surface);\n}\n.ps-model-detail .mtile .v {\n font-size: 28px;\n font-weight: 720;\n color: var(--mj-text-primary);\n letter-spacing: -.02em;\n}\n.ps-model-detail .mtile.honest {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n}\n.ps-model-detail .mtile.honest .v {\n color: var(--mj-brand-primary);\n}\n\n.ps-model-detail .stat-bar {\n display: flex;\n gap: 10px;\n margin-top: 14px;\n flex-wrap: wrap;\n}\n.ps-model-detail .stat-bar .b {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n border-radius: 8px;\n flex: 1;\n min-width: 90px;\n}\n.ps-model-detail .stat-bar .b strong {\n color: var(--mj-text-primary);\n font-size: 15px;\n}\n\n/* ---- feature importance bars ---- */\n.ps-model-detail .ps-fbar {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 8px;\n}\n.ps-model-detail .ps-fbar .name {\n width: 170px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex-shrink: 0;\n color: var(--mj-text-secondary);\n}\n.ps-model-detail .ps-fbar .track {\n flex: 1;\n height: 8px;\n background: var(--mj-bg-surface-sunken, #f3f4f6);\n border-radius: 999px;\n overflow: hidden;\n}\n.ps-model-detail .ps-fbar .track span {\n display: block;\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 999px;\n}\n.ps-model-detail .ps-fbar .track span.warn {\n background: var(--mj-status-warning, #d98213);\n}\n\n/* ---- leakage gate callout ---- */\n.ps-model-detail .ps-callout {\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n.ps-model-detail .ps-callout.gate {\n align-items: flex-start;\n}\n.ps-model-detail .ps-callout.gate i {\n font-size: 20px;\n margin-top: 2px;\n}\n.ps-model-detail .ps-callout.success {\n background: var(--mj-status-success-bg, #f0fdf4);\n border-color: color-mix(in srgb, var(--mj-status-success) 25%, transparent);\n color: var(--mj-status-success-text, #15803d);\n}\n.ps-model-detail .ps-callout.warn {\n background: var(--mj-status-warning-bg, #fffbeb);\n border-color: color-mix(in srgb, var(--mj-status-warning) 25%, transparent);\n color: var(--mj-status-warning-text, #b45309);\n}\n\n/* ---- confirmation modal ---- */\n.ps-model-detail .ps-modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.45);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n}\n.ps-model-detail .ps-modal {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n width: 100%;\n max-width: 480px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);\n overflow: hidden;\n}\n.ps-model-detail .ps-modal-head {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n}\n.ps-model-detail .ps-modal-head .ico {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: grid;\n place-items: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 15px;\n}\n.ps-model-detail .ps-modal-head.warn .ico {\n background: var(--mj-status-warning, #d98213);\n}\n.ps-model-detail .ps-modal-head.danger .ico {\n background: var(--mj-status-error, #b91c1c);\n}\n.ps-model-detail .ps-modal-head h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n}\n.ps-model-detail .ps-modal-body {\n padding: 20px;\n font-size: 13.5px;\n line-height: 1.5;\n}\n.ps-model-detail .ps-modal-foot {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 20px;\n border-top: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n background: var(--mj-bg-surface-sunken, #f9fafb);\n}\n.ps-model-detail .ps-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.ps-model-detail .ps-field label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n.ps-model-detail .ps-input {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-family: inherit;\n font-size: 13px;\n resize: vertical;\n}\n.ps-model-detail .ps-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n"] }]
|
|
679
|
-
}], null, {
|
|
859
|
+
}], null, { Model: [{
|
|
860
|
+
type: Input
|
|
861
|
+
}], model: [{
|
|
862
|
+
type: Input
|
|
863
|
+
}], Provider: [{
|
|
680
864
|
type: Input
|
|
681
865
|
}], provider: [{
|
|
682
866
|
type: Input
|
|
867
|
+
}], CurrentUser: [{
|
|
868
|
+
type: Input
|
|
683
869
|
}], currentUser: [{
|
|
684
870
|
type: Input
|
|
871
|
+
}], ShowActions: [{
|
|
872
|
+
type: Input
|
|
685
873
|
}], showActions: [{
|
|
686
874
|
type: Input
|
|
875
|
+
}], StatusChanged: [{
|
|
876
|
+
type: Output
|
|
687
877
|
}], statusChanged: [{
|
|
688
878
|
type: Output
|
|
689
879
|
}], displayName: [{
|