@memberjunction/ng-dashboards 6.1.2 → 6.2.0-edge.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/AI/components/vectors/vector-management-resource.component.d.ts +6 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +99 -45
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +4 -0
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +16 -6
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +4 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +14 -4
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +2 -2
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/DevTools/graphql-console.component.d.ts.map +1 -1
- package/dist/DevTools/graphql-console.component.js +2 -0
- package/dist/DevTools/graphql-console.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +2 -0
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts +4 -12
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js +39 -78
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +3 -0
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +7 -6
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts +3 -0
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +7 -6
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/at-risk.view-models.d.ts +41 -3
- package/dist/PredictiveStudio/at-risk.view-models.d.ts.map +1 -1
- package/dist/PredictiveStudio/at-risk.view-models.js +99 -6
- package/dist/PredictiveStudio/at-risk.view-models.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.d.ts +4 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.js +61 -37
- package/dist/PredictiveStudio/components/ps-catalog.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts +12 -0
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.js +426 -184
- package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts +84 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js +1397 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts +66 -34
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipelines.component.js +2456 -743
- package/dist/PredictiveStudio/components/ps-pipelines.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts +194 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js +1902 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-production.component.d.ts +17 -1
- package/dist/PredictiveStudio/components/ps-production.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-production.component.js +653 -372
- package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-registry.component.d.ts +21 -61
- package/dist/PredictiveStudio/components/ps-registry.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-registry.component.js +214 -681
- package/dist/PredictiveStudio/components/ps-registry.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts +49 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js +658 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js.map +1 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts +42 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts.map +1 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js +90 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js.map +1 -0
- package/dist/PredictiveStudio/predictive-studio.view-models.d.ts +14 -2
- package/dist/PredictiveStudio/predictive-studio.view-models.d.ts.map +1 -1
- package/dist/PredictiveStudio/predictive-studio.view-models.js +41 -5
- package/dist/PredictiveStudio/predictive-studio.view-models.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts +9 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.js +178 -65
- package/dist/PredictiveStudio/resources/ps-models-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts +9 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +307 -369
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-resource-base.js +1 -1
- package/dist/PredictiveStudio/resources/ps-resource-base.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts +17 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js +309 -138
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.d.ts +1 -0
- package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +6 -5
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
- package/dist/predictive-studio-dashboards.module.d.ts +10 -8
- package/dist/predictive-studio-dashboards.module.d.ts.map +1 -1
- package/dist/predictive-studio-dashboards.module.js +13 -3
- package/dist/predictive-studio-dashboards.module.js.map +1 -1
- package/package.json +64 -63
|
@@ -5,7 +5,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';
|
|
8
|
-
import { RegisterClass } from '@memberjunction/global';
|
|
8
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
9
|
+
import { UserInfoEngine } from '@memberjunction/core-entities';
|
|
9
10
|
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
10
11
|
import { PSResourceBase } from './ps-resource-base';
|
|
11
12
|
import { MODELS_SECTIONS, sectionGroups, sectionsInGroup, sectionLabel, hasSection } from '../predictive-studio.nav';
|
|
@@ -14,8 +15,9 @@ import { validateStringParam } from '../../shared/agent-tool-validation';
|
|
|
14
15
|
import * as i0 from "@angular/core";
|
|
15
16
|
import * as i1 from "@memberjunction/ng-ui-components";
|
|
16
17
|
import * as i2 from "@memberjunction/ng-shared-generic";
|
|
17
|
-
import * as i3 from "
|
|
18
|
-
import * as i4 from "../components/ps-
|
|
18
|
+
import * as i3 from "angular-split";
|
|
19
|
+
import * as i4 from "../components/ps-registry.component";
|
|
20
|
+
import * as i5 from "../components/ps-production.component";
|
|
19
21
|
const _forTrack0 = ($index, $item) => $item.key;
|
|
20
22
|
function PSModelsResourceComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
21
23
|
i0.ɵɵelement(0, "mj-loading", 2);
|
|
@@ -42,72 +44,110 @@ function PSModelsResourceComponent_Conditional_3_Template(rf, ctx) { if (rf & 1)
|
|
|
42
44
|
i0.ɵɵadvance(2);
|
|
43
45
|
i0.ɵɵtextInterpolate(ctx_r1.loadError);
|
|
44
46
|
} }
|
|
45
|
-
function
|
|
46
|
-
i0.ɵɵ
|
|
47
|
+
function PSModelsResourceComponent_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
48
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
49
|
+
i0.ɵɵelementStart(0, "div", 11)(1, "button", 18);
|
|
50
|
+
i0.ɵɵlistener("click", function PSModelsResourceComponent_Conditional_4_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleNav()); });
|
|
51
|
+
i0.ɵɵelement(2, "i", 19);
|
|
52
|
+
i0.ɵɵelementEnd();
|
|
53
|
+
i0.ɵɵelementStart(3, "div", 20);
|
|
54
|
+
i0.ɵɵelement(4, "i", 21);
|
|
55
|
+
i0.ɵɵtext(5, " Models");
|
|
56
|
+
i0.ɵɵelementEnd()();
|
|
57
|
+
} }
|
|
58
|
+
function PSModelsResourceComponent_Conditional_4_Conditional_3_For_8_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
59
|
+
i0.ɵɵelementStart(0, "div", 27);
|
|
47
60
|
i0.ɵɵtext(1);
|
|
48
61
|
i0.ɵɵelementEnd();
|
|
49
62
|
} if (rf & 2) {
|
|
50
|
-
const
|
|
63
|
+
const group_r6 = i0.ɵɵnextContext().$implicit;
|
|
51
64
|
i0.ɵɵadvance();
|
|
52
|
-
i0.ɵɵtextInterpolate(
|
|
65
|
+
i0.ɵɵtextInterpolate(group_r6);
|
|
53
66
|
} }
|
|
54
|
-
function
|
|
55
|
-
const
|
|
56
|
-
i0.ɵɵelementStart(0, "button",
|
|
57
|
-
i0.ɵɵlistener("click", function
|
|
67
|
+
function PSModelsResourceComponent_Conditional_4_Conditional_3_For_8_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
68
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
69
|
+
i0.ɵɵelementStart(0, "button", 29);
|
|
70
|
+
i0.ɵɵlistener("click", function PSModelsResourceComponent_Conditional_4_Conditional_3_For_8_For_2_Template_button_click_0_listener() { const item_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.selectSection(item_r8.key)); });
|
|
58
71
|
i0.ɵɵelement(1, "i");
|
|
59
72
|
i0.ɵɵelementStart(2, "span");
|
|
60
73
|
i0.ɵɵtext(3);
|
|
61
74
|
i0.ɵɵelementEnd()();
|
|
62
75
|
} if (rf & 2) {
|
|
63
|
-
const
|
|
64
|
-
const ctx_r1 = i0.ɵɵnextContext(
|
|
65
|
-
i0.ɵɵclassProp("active", ctx_r1.activeSection ===
|
|
66
|
-
i0.ɵɵattribute("data-testid", "ps-nav-" +
|
|
76
|
+
const item_r8 = ctx.$implicit;
|
|
77
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
78
|
+
i0.ɵɵclassProp("active", ctx_r1.activeSection === item_r8.key);
|
|
79
|
+
i0.ɵɵattribute("data-testid", "ps-nav-" + item_r8.key);
|
|
67
80
|
i0.ɵɵadvance();
|
|
68
|
-
i0.ɵɵclassMap(
|
|
81
|
+
i0.ɵɵclassMap(item_r8.icon);
|
|
69
82
|
i0.ɵɵadvance(2);
|
|
70
|
-
i0.ɵɵtextInterpolate(
|
|
83
|
+
i0.ɵɵtextInterpolate(item_r8.label);
|
|
71
84
|
} }
|
|
72
|
-
function
|
|
73
|
-
i0.ɵɵconditionalCreate(0,
|
|
74
|
-
i0.ɵɵrepeaterCreate(1,
|
|
85
|
+
function PSModelsResourceComponent_Conditional_4_Conditional_3_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
86
|
+
i0.ɵɵconditionalCreate(0, PSModelsResourceComponent_Conditional_4_Conditional_3_For_8_Conditional_0_Template, 2, 1, "div", 27);
|
|
87
|
+
i0.ɵɵrepeaterCreate(1, PSModelsResourceComponent_Conditional_4_Conditional_3_For_8_For_2_Template, 4, 6, "button", 28, _forTrack0);
|
|
75
88
|
} if (rf & 2) {
|
|
76
|
-
const
|
|
77
|
-
const ctx_r1 = i0.ɵɵnextContext(
|
|
78
|
-
i0.ɵɵconditional(
|
|
89
|
+
const group_r6 = ctx.$implicit;
|
|
90
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
91
|
+
i0.ɵɵconditional(group_r6 ? 0 : -1);
|
|
79
92
|
i0.ɵɵadvance();
|
|
80
|
-
i0.ɵɵrepeater(ctx_r1.itemsForGroup(
|
|
93
|
+
i0.ɵɵrepeater(ctx_r1.itemsForGroup(group_r6));
|
|
81
94
|
} }
|
|
82
|
-
function
|
|
83
|
-
i0.ɵɵ
|
|
95
|
+
function PSModelsResourceComponent_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
96
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
97
|
+
i0.ɵɵelementStart(0, "as-split-area", 13)(1, "aside", 22)(2, "div", 23)(3, "span", 24);
|
|
98
|
+
i0.ɵɵtext(4, "Lifecycle");
|
|
99
|
+
i0.ɵɵelementEnd();
|
|
100
|
+
i0.ɵɵelementStart(5, "button", 25);
|
|
101
|
+
i0.ɵɵlistener("click", function PSModelsResourceComponent_Conditional_4_Conditional_3_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleNav()); });
|
|
102
|
+
i0.ɵɵelement(6, "i", 26);
|
|
103
|
+
i0.ɵɵelementEnd()();
|
|
104
|
+
i0.ɵɵrepeaterCreate(7, PSModelsResourceComponent_Conditional_4_Conditional_3_For_8_Template, 3, 1, null, null, i0.ɵɵrepeaterTrackByIdentity);
|
|
105
|
+
i0.ɵɵelementEnd()();
|
|
84
106
|
} if (rf & 2) {
|
|
85
107
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
86
|
-
i0.ɵɵproperty("
|
|
108
|
+
i0.ɵɵproperty("size", ctx_r1.navSizePct)("minSize", 10)("maxSize", 30);
|
|
109
|
+
i0.ɵɵadvance(7);
|
|
110
|
+
i0.ɵɵrepeater(ctx_r1.groups);
|
|
87
111
|
} }
|
|
88
112
|
function PSModelsResourceComponent_Conditional_4_Case_6_Template(rf, ctx) { if (rf & 1) {
|
|
89
|
-
i0.ɵɵelement(0, "ps-
|
|
113
|
+
i0.ɵɵelement(0, "ps-registry", 16);
|
|
114
|
+
} if (rf & 2) {
|
|
115
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
116
|
+
i0.ɵɵproperty("engine", ctx_r1.engine)("provider", ctx_r1.ProviderToUse)("currentUser", ctx_r1.ProviderToUse.CurrentUser)("initialModelId", ctx_r1.initialModelId);
|
|
117
|
+
} }
|
|
118
|
+
function PSModelsResourceComponent_Conditional_4_Case_7_Template(rf, ctx) { if (rf & 1) {
|
|
119
|
+
i0.ɵɵelement(0, "ps-production", 17);
|
|
90
120
|
} if (rf & 2) {
|
|
91
121
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
92
122
|
i0.ɵɵproperty("engine", ctx_r1.engine);
|
|
93
123
|
} }
|
|
94
124
|
function PSModelsResourceComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
95
|
-
i0.ɵɵ
|
|
96
|
-
i0.ɵɵ
|
|
97
|
-
i0.ɵɵ
|
|
98
|
-
i0.ɵɵelementStart(
|
|
99
|
-
i0.ɵɵ
|
|
100
|
-
i0.ɵɵ
|
|
125
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
126
|
+
i0.ɵɵelementStart(0, "div", 10);
|
|
127
|
+
i0.ɵɵconditionalCreate(1, PSModelsResourceComponent_Conditional_4_Conditional_1_Template, 6, 0, "div", 11);
|
|
128
|
+
i0.ɵɵelementStart(2, "as-split", 12);
|
|
129
|
+
i0.ɵɵlistener("dragEnd", function PSModelsResourceComponent_Conditional_4_Template_as_split_dragEnd_2_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSplitDragEnd($event.sizes)); });
|
|
130
|
+
i0.ɵɵconditionalCreate(3, PSModelsResourceComponent_Conditional_4_Conditional_3_Template, 9, 3, "as-split-area", 13);
|
|
131
|
+
i0.ɵɵelementStart(4, "as-split-area", 14)(5, "section", 15);
|
|
132
|
+
i0.ɵɵconditionalCreate(6, PSModelsResourceComponent_Conditional_4_Case_6_Template, 1, 4, "ps-registry", 16)(7, PSModelsResourceComponent_Conditional_4_Case_7_Template, 1, 1, "ps-production", 17);
|
|
133
|
+
i0.ɵɵelementEnd()()()();
|
|
101
134
|
} if (rf & 2) {
|
|
102
|
-
let
|
|
135
|
+
let tmp_9_0;
|
|
103
136
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
104
|
-
i0.ɵɵ
|
|
105
|
-
i0.ɵɵ
|
|
106
|
-
i0.ɵɵ
|
|
107
|
-
i0.ɵɵ
|
|
137
|
+
i0.ɵɵclassProp("nav-collapsed", ctx_r1.isNavCollapsed);
|
|
138
|
+
i0.ɵɵadvance();
|
|
139
|
+
i0.ɵɵconditional(ctx_r1.isNavCollapsed ? 1 : -1);
|
|
140
|
+
i0.ɵɵadvance();
|
|
141
|
+
i0.ɵɵproperty("gutterSize", ctx_r1.isNavCollapsed ? 0 : 6);
|
|
142
|
+
i0.ɵɵadvance();
|
|
143
|
+
i0.ɵɵconditional(!ctx_r1.isNavCollapsed ? 3 : -1);
|
|
144
|
+
i0.ɵɵadvance();
|
|
145
|
+
i0.ɵɵproperty("size", ctx_r1.isNavCollapsed ? 100 : ctx_r1.contentSizePct)("minSize", 50);
|
|
146
|
+
i0.ɵɵadvance();
|
|
147
|
+
i0.ɵɵclassProp("fill", ctx_r1.activeSection === "registry" || ctx_r1.activeSection === "production");
|
|
108
148
|
i0.ɵɵattribute("data-testid", "ps-panel-" + ctx_r1.activeSection);
|
|
109
149
|
i0.ɵɵadvance();
|
|
110
|
-
i0.ɵɵconditional((
|
|
150
|
+
i0.ɵɵconditional((tmp_9_0 = ctx_r1.activeSection) === "registry" ? 6 : tmp_9_0 === "production" ? 7 : -1);
|
|
111
151
|
} }
|
|
112
152
|
/**
|
|
113
153
|
* **Models** — the trained-model lifecycle door (one of Predictive Studio's three consolidated nav
|
|
@@ -124,18 +164,68 @@ let PSModelsResourceComponent = class PSModelsResourceComponent extends PSResour
|
|
|
124
164
|
cdrLocal = inject(ChangeDetectorRef);
|
|
125
165
|
activeSection = 'registry';
|
|
126
166
|
sections = MODELS_SECTIONS;
|
|
167
|
+
initialModelId;
|
|
168
|
+
isNavCollapsed = false;
|
|
169
|
+
navSizePct = 14;
|
|
170
|
+
contentSizePct = 86;
|
|
127
171
|
ngOnInit() {
|
|
128
172
|
super.ngOnInit();
|
|
129
|
-
const
|
|
173
|
+
const qp = this.GetQueryParams();
|
|
174
|
+
const initial = qp['section'];
|
|
130
175
|
if (initial && hasSection(this.sections, initial))
|
|
131
176
|
this.activeSection = initial;
|
|
177
|
+
if (qp['modelId'])
|
|
178
|
+
this.initialModelId = qp['modelId'];
|
|
179
|
+
this.loadLayoutPrefs();
|
|
132
180
|
}
|
|
133
|
-
|
|
181
|
+
toggleNav() {
|
|
182
|
+
this.isNavCollapsed = !this.isNavCollapsed;
|
|
183
|
+
this.saveLayoutPrefs();
|
|
184
|
+
this.cdrLocal.detectChanges();
|
|
185
|
+
}
|
|
186
|
+
onSplitDragEnd(sizes) {
|
|
187
|
+
if (Array.isArray(sizes) && sizes.length === 2 && typeof sizes[0] === 'number' && typeof sizes[1] === 'number') {
|
|
188
|
+
this.navSizePct = Math.round(sizes[0]);
|
|
189
|
+
this.contentSizePct = Math.round(sizes[1]);
|
|
190
|
+
this.saveLayoutPrefs();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
loadLayoutPrefs() {
|
|
194
|
+
const raw = UserInfoEngine.Instance.GetSetting('mj.predictiveStudio.models.layout');
|
|
195
|
+
if (raw) {
|
|
196
|
+
try {
|
|
197
|
+
const parsed = JSON.parse(raw);
|
|
198
|
+
if (typeof parsed.navSizePct === 'number' && parsed.navSizePct >= 10 && parsed.navSizePct <= 35) {
|
|
199
|
+
this.navSizePct = parsed.navSizePct;
|
|
200
|
+
this.contentSizePct = 100 - parsed.navSizePct;
|
|
201
|
+
}
|
|
202
|
+
if (typeof parsed.isNavCollapsed === 'boolean') {
|
|
203
|
+
this.isNavCollapsed = parsed.isNavCollapsed;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch { }
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
saveLayoutPrefs() {
|
|
210
|
+
const prefs = {
|
|
211
|
+
navSizePct: this.navSizePct,
|
|
212
|
+
contentSizePct: this.contentSizePct,
|
|
213
|
+
isNavCollapsed: this.isNavCollapsed,
|
|
214
|
+
};
|
|
215
|
+
UserInfoEngine.Instance.SetSettingDebounced('mj.predictiveStudio.models.layout', JSON.stringify(prefs));
|
|
216
|
+
}
|
|
217
|
+
async OnQueryParamsChanged(params, _source) {
|
|
134
218
|
const next = params['section'];
|
|
135
219
|
if (next && next !== this.activeSection && hasSection(this.sections, next)) {
|
|
136
220
|
this.activeSection = next;
|
|
137
|
-
this.cdrLocal.detectChanges();
|
|
138
221
|
}
|
|
222
|
+
if (params['modelId']) {
|
|
223
|
+
this.initialModelId = params['modelId'];
|
|
224
|
+
if (this.engine && !this.engine.Models.some((m) => UUIDsEqual(m.ID, params['modelId']))) {
|
|
225
|
+
await this.engine.Config(true, this.ProviderToUse.CurrentUser ?? undefined, this.ProviderToUse);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
this.cdrLocal.detectChanges();
|
|
139
229
|
}
|
|
140
230
|
/** Deep agent context for the Models door: active section + trained-model lifecycle counts. */
|
|
141
231
|
extraAgentContext() {
|
|
@@ -195,10 +285,10 @@ let PSModelsResourceComponent = class PSModelsResourceComponent extends PSResour
|
|
|
195
285
|
this.cdrLocal.detectChanges();
|
|
196
286
|
}
|
|
197
287
|
static ɵfac = /*@__PURE__*/ (() => { let ɵPSModelsResourceComponent_BaseFactory; return function PSModelsResourceComponent_Factory(__ngFactoryType__) { return (ɵPSModelsResourceComponent_BaseFactory || (ɵPSModelsResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(PSModelsResourceComponent)))(__ngFactoryType__ || PSModelsResourceComponent); }; })();
|
|
198
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PSModelsResourceComponent, selectors: [["mj-ps-models-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 5, consts: [[3, "Title", "Subtitle"], [3, "Flex", "Padding"], ["text", "Loading Models\u2026", "size", "medium"], ["data-testid", "ps-load-error", "role", "alert", 1, "ps-load-error"], ["data-testid", "ps-models-shell", 1, "ps-models-host"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "ps-load-error-text"], [1, "ps-load-error-detail"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-rotate-right"], [1, "ps-
|
|
288
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PSModelsResourceComponent, selectors: [["mj-ps-models-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 5, consts: [[3, "Title", "Subtitle"], [3, "Flex", "Padding"], ["text", "Loading Models\u2026", "size", "medium"], ["data-testid", "ps-load-error", "role", "alert", 1, "ps-load-error"], ["data-testid", "ps-models-shell", 1, "ps-models-host", 3, "nav-collapsed"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "ps-load-error-text"], [1, "ps-load-error-detail"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-rotate-right"], ["data-testid", "ps-models-shell", 1, "ps-models-host"], ["role", "region", "aria-label", "Models navigation (collapsed)", 1, "ps-nav-collapsed-strip"], ["direction", "horizontal", "unit", "percent", 1, "models-splitter", 3, "dragEnd", "gutterSize"], [3, "size", "minSize", "maxSize"], [3, "size", "minSize"], [1, "ps-content"], [3, "engine", "provider", "currentUser", "initialModelId"], [3, "engine"], ["type", "button", "aria-label", "Expand models navigation", "title", "Expand navigation", 1, "ps-nav-rail-collapse", 3, "click"], [1, "fa-solid", "fa-chevron-right"], [1, "ps-nav-collapsed-strip-label"], [1, "fa-solid", "fa-cubes"], [1, "ps-leftnav"], [1, "ps-leftnav-header"], [1, "ps-leftnav-title"], ["type", "button", "title", "Collapse navigation", "aria-label", "Collapse navigation", 1, "ps-leftnav-collapse-btn", 3, "click"], [1, "fa-solid", "fa-chevron-left"], [1, "ps-nav-group"], [1, "ps-nav-item", 3, "active"], [1, "ps-nav-item", 3, "click"]], template: function PSModelsResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
199
289
|
i0.ɵɵelement(0, "mj-page-header-interior", 0);
|
|
200
290
|
i0.ɵɵelementStart(1, "mj-page-body-interior", 1);
|
|
201
|
-
i0.ɵɵconditionalCreate(2, PSModelsResourceComponent_Conditional_2_Template, 1, 0, "mj-loading", 2)(3, PSModelsResourceComponent_Conditional_3_Template, 10, 2, "div", 3)(4, PSModelsResourceComponent_Conditional_4_Template,
|
|
291
|
+
i0.ɵɵconditionalCreate(2, PSModelsResourceComponent_Conditional_2_Template, 1, 0, "mj-loading", 2)(3, PSModelsResourceComponent_Conditional_3_Template, 10, 2, "div", 3)(4, PSModelsResourceComponent_Conditional_4_Template, 8, 11, "div", 4);
|
|
202
292
|
i0.ɵɵelementEnd();
|
|
203
293
|
} if (rf & 2) {
|
|
204
294
|
i0.ɵɵproperty("Title", ctx.activeLabel)("Subtitle", ctx.activeSubtitle);
|
|
@@ -206,7 +296,7 @@ let PSModelsResourceComponent = class PSModelsResourceComponent extends PSResour
|
|
|
206
296
|
i0.ɵɵproperty("Flex", true)("Padding", false);
|
|
207
297
|
i0.ɵɵadvance();
|
|
208
298
|
i0.ɵɵconditional(ctx.isLoading ? 2 : ctx.loadError ? 3 : 4);
|
|
209
|
-
} }, dependencies: [i1.MJButtonDirective, i1.MJPageHeaderInteriorComponent, i1.MJPageBodyInteriorComponent, i2.LoadingComponent, i3.
|
|
299
|
+
} }, dependencies: [i1.MJButtonDirective, i1.MJPageHeaderInteriorComponent, i1.MJPageBodyInteriorComponent, i2.LoadingComponent, i3.SplitComponent, i3.SplitAreaComponent, i4.PSRegistryComponent, i5.PSProductionComponent], styles: ["[_nghost-%COMP%] { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-models-host[_ngcontent-%COMP%] { display: flex; flex: 1; min-height: 0; overflow: hidden; width: 100%; height: 100%; }\n .models-splitter[_ngcontent-%COMP%] { flex: 1; width: 100%; height: 100%; min-height: 0; min-width: 0; background: transparent; }\n .models-splitter[_ngcontent-%COMP%] .as-split-gutter[_ngcontent-%COMP%] { background: transparent; transition: background-color 0.15s ease; position: relative; }\n .models-splitter[_ngcontent-%COMP%] .as-split-gutter[_ngcontent-%COMP%]:hover { background-color: var(--mj-brand-primary, #6366f1); }\n .models-splitter[_ngcontent-%COMP%] .as-split-gutter[_ngcontent-%COMP%]::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 2px; height: 24px; border-radius: 1px; background: var(--mj-border-strong, #cbd5e1); }\n .models-splitter[_ngcontent-%COMP%] .as-split-gutter[_ngcontent-%COMP%]:hover::after { background: #ffffff; }\n\n .ps-nav-collapsed-strip[_ngcontent-%COMP%] { width: 44px; min-width: 44px; max-width: 44px; flex: none; background: var(--mj-bg-surface); border-right: 1px solid var(--mj-border-default); display: flex; flex-direction: column; align-items: center; padding: 10px 0; gap: 14px; z-index: 2; }\n .ps-nav-rail-collapse[_ngcontent-%COMP%] { background: var(--mj-bg-surface-subtle); border: 1px solid var(--mj-border-default); border-radius: 6px; color: var(--mj-text-secondary); cursor: pointer; display: grid; place-items: center; width: 28px; height: 28px; padding: 0; font-size: 11px; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease; }\n .ps-nav-rail-collapse[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); border-color: var(--mj-border-strong); }\n .ps-nav-collapsed-strip-label[_ngcontent-%COMP%] { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; color: var(--mj-text-muted); display: flex; align-items: center; gap: 8px; text-transform: uppercase; }\n\n .ps-leftnav[_ngcontent-%COMP%] { width: 100%; height: 100%; border-right: 1px solid var(--mj-border-default); background: var(--mj-bg-surface-card); overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 2px; box-sizing: border-box; }\n .ps-leftnav-header[_ngcontent-%COMP%] { display: flex; align-items: center; justify-content: space-between; padding: 4px 6px 8px; border-bottom: 1px solid var(--mj-border-subtle); margin-bottom: 4px; }\n .ps-leftnav-title[_ngcontent-%COMP%] { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--mj-text-muted); }\n .ps-leftnav-collapse-btn[_ngcontent-%COMP%] { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 6px; border: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); color: var(--mj-text-muted); cursor: pointer; transition: all 0.15s ease; padding: 0; }\n .ps-leftnav-collapse-btn[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); border-color: var(--mj-border-strong); }\n\n .ps-nav-group[_ngcontent-%COMP%] { font-size: var(--mj-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--mj-text-muted); padding: 10px 8px 4px; }\n .ps-nav-item[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 8px 10px; border: none; background: transparent; border-radius: var(--mj-radius-md); cursor: pointer; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); font-weight: 500; transition: background .12s, color .12s; }\n .ps-nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { width: 18px; text-align: center; color: var(--mj-text-muted); }\n .ps-nav-item[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .ps-nav-item.active[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); color: var(--mj-brand-primary); font-weight: 600; }\n .ps-nav-item.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n .ps-content[_ngcontent-%COMP%] { width: 100%; height: 100%; flex: 1; min-width: 0; overflow-y: auto; padding: 8px 14px 24px; }\n \n\n .ps-content.fill[_ngcontent-%COMP%] { overflow: hidden; display: flex; flex-direction: column; padding-bottom: 14px; }\n .ps-content.fill[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] { flex: 1; min-height: 0; display: flex; flex-direction: column; }\n .ps-load-error[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 14px; max-width: 620px; margin: 32px auto; padding: 18px 20px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-lg); }\n .ps-load-error[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] { font-size: 24px; color: var(--mj-status-error); }\n .ps-load-error-text[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n .ps-load-error-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] { color: var(--mj-text-primary); }\n .ps-load-error-detail[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); word-break: break-word; }"], changeDetection: 0 });
|
|
210
300
|
};
|
|
211
301
|
PSModelsResourceComponent = __decorate([
|
|
212
302
|
RegisterClass(BaseResourceComponent, 'PredictiveStudioModelsResource')
|
|
@@ -230,31 +320,54 @@ export { PSModelsResourceComponent };
|
|
|
230
320
|
<button mjButton variant="secondary" size="sm" (click)="retryLoad()"><i class="fa-solid fa-rotate-right"></i> Try again</button>
|
|
231
321
|
</div>
|
|
232
322
|
} @else {
|
|
233
|
-
<div class="ps-models-host" data-testid="ps-models-shell">
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
</aside>
|
|
323
|
+
<div class="ps-models-host" [class.nav-collapsed]="isNavCollapsed" data-testid="ps-models-shell">
|
|
324
|
+
@if (isNavCollapsed) {
|
|
325
|
+
<div class="ps-nav-collapsed-strip" role="region" aria-label="Models navigation (collapsed)">
|
|
326
|
+
<button class="ps-nav-rail-collapse" type="button" (click)="toggleNav()" aria-label="Expand models navigation" title="Expand navigation">
|
|
327
|
+
<i class="fa-solid fa-chevron-right"></i>
|
|
328
|
+
</button>
|
|
329
|
+
<div class="ps-nav-collapsed-strip-label"><i class="fa-solid fa-cubes"></i> Models</div>
|
|
330
|
+
</div>
|
|
331
|
+
}
|
|
245
332
|
|
|
246
|
-
<
|
|
247
|
-
@
|
|
248
|
-
|
|
249
|
-
|
|
333
|
+
<as-split direction="horizontal" class="models-splitter" unit="percent" [gutterSize]="isNavCollapsed ? 0 : 6" (dragEnd)="onSplitDragEnd($event.sizes)">
|
|
334
|
+
@if (!isNavCollapsed) {
|
|
335
|
+
<as-split-area [size]="navSizePct" [minSize]="10" [maxSize]="30">
|
|
336
|
+
<aside class="ps-leftnav">
|
|
337
|
+
<div class="ps-leftnav-header">
|
|
338
|
+
<span class="ps-leftnav-title">Lifecycle</span>
|
|
339
|
+
<button class="ps-leftnav-collapse-btn" type="button" (click)="toggleNav()" title="Collapse navigation" aria-label="Collapse navigation">
|
|
340
|
+
<i class="fa-solid fa-chevron-left"></i>
|
|
341
|
+
</button>
|
|
342
|
+
</div>
|
|
343
|
+
@for (group of groups; track group) {
|
|
344
|
+
@if (group) { <div class="ps-nav-group">{{ group }}</div> }
|
|
345
|
+
@for (item of itemsForGroup(group); track item.key) {
|
|
346
|
+
<button class="ps-nav-item" [class.active]="activeSection === item.key"
|
|
347
|
+
[attr.data-testid]="'ps-nav-' + item.key" (click)="selectSection(item.key)">
|
|
348
|
+
<i [class]="item.icon"></i> <span>{{ item.label }}</span>
|
|
349
|
+
</button>
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
</aside>
|
|
353
|
+
</as-split-area>
|
|
250
354
|
}
|
|
251
|
-
|
|
355
|
+
|
|
356
|
+
<as-split-area [size]="isNavCollapsed ? 100 : contentSizePct" [minSize]="50">
|
|
357
|
+
<section class="ps-content" [class.fill]="activeSection === 'registry' || activeSection === 'production'" [attr.data-testid]="'ps-panel-' + activeSection">
|
|
358
|
+
@switch (activeSection) {
|
|
359
|
+
@case ('registry') { <ps-registry [engine]="engine" [provider]="ProviderToUse" [currentUser]="ProviderToUse.CurrentUser" [initialModelId]="initialModelId"></ps-registry> }
|
|
360
|
+
@case ('production') { <ps-production [engine]="engine"></ps-production> }
|
|
361
|
+
}
|
|
362
|
+
</section>
|
|
363
|
+
</as-split-area>
|
|
364
|
+
</as-split>
|
|
252
365
|
</div>
|
|
253
366
|
}
|
|
254
367
|
</mj-page-body-interior>
|
|
255
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-models-host { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .ps-
|
|
368
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-models-host { display: flex; flex: 1; min-height: 0; overflow: hidden; width: 100%; height: 100%; }\n .models-splitter { flex: 1; width: 100%; height: 100%; min-height: 0; min-width: 0; background: transparent; }\n .models-splitter .as-split-gutter { background: transparent; transition: background-color 0.15s ease; position: relative; }\n .models-splitter .as-split-gutter:hover { background-color: var(--mj-brand-primary, #6366f1); }\n .models-splitter .as-split-gutter::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 2px; height: 24px; border-radius: 1px; background: var(--mj-border-strong, #cbd5e1); }\n .models-splitter .as-split-gutter:hover::after { background: #ffffff; }\n\n .ps-nav-collapsed-strip { width: 44px; min-width: 44px; max-width: 44px; flex: none; background: var(--mj-bg-surface); border-right: 1px solid var(--mj-border-default); display: flex; flex-direction: column; align-items: center; padding: 10px 0; gap: 14px; z-index: 2; }\n .ps-nav-rail-collapse { background: var(--mj-bg-surface-subtle); border: 1px solid var(--mj-border-default); border-radius: 6px; color: var(--mj-text-secondary); cursor: pointer; display: grid; place-items: center; width: 28px; height: 28px; padding: 0; font-size: 11px; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease; }\n .ps-nav-rail-collapse:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); border-color: var(--mj-border-strong); }\n .ps-nav-collapsed-strip-label { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; color: var(--mj-text-muted); display: flex; align-items: center; gap: 8px; text-transform: uppercase; }\n\n .ps-leftnav { width: 100%; height: 100%; border-right: 1px solid var(--mj-border-default); background: var(--mj-bg-surface-card); overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 2px; box-sizing: border-box; }\n .ps-leftnav-header { display: flex; align-items: center; justify-content: space-between; padding: 4px 6px 8px; border-bottom: 1px solid var(--mj-border-subtle); margin-bottom: 4px; }\n .ps-leftnav-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--mj-text-muted); }\n .ps-leftnav-collapse-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 6px; border: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); color: var(--mj-text-muted); cursor: pointer; transition: all 0.15s ease; padding: 0; }\n .ps-leftnav-collapse-btn:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); border-color: var(--mj-border-strong); }\n\n .ps-nav-group { font-size: var(--mj-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--mj-text-muted); padding: 10px 8px 4px; }\n .ps-nav-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 8px 10px; border: none; background: transparent; border-radius: var(--mj-radius-md); cursor: pointer; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); font-weight: 500; transition: background .12s, color .12s; }\n .ps-nav-item i { width: 18px; text-align: center; color: var(--mj-text-muted); }\n .ps-nav-item:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .ps-nav-item.active { background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); color: var(--mj-brand-primary); font-weight: 600; }\n .ps-nav-item.active i { color: var(--mj-brand-primary); }\n .ps-content { width: 100%; height: 100%; flex: 1; min-width: 0; overflow-y: auto; padding: 8px 14px 24px; }\n /* Fill mode (registry): the section stops page-scrolling so the panel's inner\n columns (model list / detail) can each own their scrollbar. */\n .ps-content.fill { overflow: hidden; display: flex; flex-direction: column; padding-bottom: 14px; }\n .ps-content.fill > * { flex: 1; min-height: 0; display: flex; flex-direction: column; }\n .ps-load-error { display: flex; align-items: center; gap: 14px; max-width: 620px; margin: 32px auto; padding: 18px 20px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-lg); }\n .ps-load-error > i { font-size: 24px; color: var(--mj-status-error); }\n .ps-load-error-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n .ps-load-error-text strong { color: var(--mj-text-primary); }\n .ps-load-error-detail { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); word-break: break-word; }\n "] }]
|
|
256
369
|
}], null, null); })();
|
|
257
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PSModelsResourceComponent, { className: "PSModelsResourceComponent", filePath: "src/PredictiveStudio/resources/ps-models-resource.component.ts", lineNumber:
|
|
370
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PSModelsResourceComponent, { className: "PSModelsResourceComponent", filePath: "src/PredictiveStudio/resources/ps-models-resource.component.ts", lineNumber: 126 }); })();
|
|
258
371
|
/** Tree-shaking prevention — called from the subpath module so the @RegisterClass survives bundling. */
|
|
259
372
|
export function LoadPSModelsResource() {
|
|
260
373
|
// intentionally empty
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ps-models-resource.component.js","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-models-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { PSResourceBase } from './ps-resource-base';\nimport { PSPanelKey } from '../predictive-studio.types';\nimport { MODELS_SECTIONS, PSSection, sectionGroups, sectionsInGroup, sectionLabel, hasSection } from '../predictive-studio.nav';\nimport { buildModelsAgentContext, resolvePSRecord, buildPSNotFoundError } from '../predictive-studio-agent-context';\nimport { validateStringParam } from '../../shared/agent-tool-validation';\n\n/**\n * **Models** — the trained-model lifecycle door (one of Predictive Studio's three consolidated nav\n * items, alongside `Predictions` and `Studio`). Hosts the registry + production section panels\n * (`ps-registry`, `ps-production`) behind an internal left-nav. The active section round-trips through\n * the `section` query param, so the `Overview` panel's cross-door \"view in production\" links (and any\n * deep link) can land directly on the right section. No docked copilot here — these are read/manage\n * surfaces; model creation + the Model Dev Agent live in the `Studio` and `Predictions` doors.\n */\n@RegisterClass(BaseResourceComponent, 'PredictiveStudioModelsResource')\n@Component({\n standalone: false,\n selector: 'mj-ps-models-resource',\n template: `\n <mj-page-header-interior [Title]=\"activeLabel\" [Subtitle]=\"activeSubtitle\">\n </mj-page-header-interior>\n <mj-page-body-interior [Flex]=\"true\" [Padding]=\"false\">\n @if (isLoading) {\n <mj-loading text=\"Loading Models…\" size=\"medium\"></mj-loading>\n } @else if (loadError) {\n <div class=\"ps-load-error\" data-testid=\"ps-load-error\" role=\"alert\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div class=\"ps-load-error-text\">\n <strong>Couldn't load {{ sectionTitle }}</strong>\n <span class=\"ps-load-error-detail\">{{ loadError }}</span>\n </div>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"retryLoad()\"><i class=\"fa-solid fa-rotate-right\"></i> Try again</button>\n </div>\n } @else {\n <div class=\"ps-models-host\" data-testid=\"ps-models-shell\">\n <aside class=\"ps-leftnav\">\n @for (group of groups; track group) {\n @if (group) { <div class=\"ps-nav-group\">{{ group }}</div> }\n @for (item of itemsForGroup(group); track item.key) {\n <button class=\"ps-nav-item\" [class.active]=\"activeSection === item.key\"\n [attr.data-testid]=\"'ps-nav-' + item.key\" (click)=\"selectSection(item.key)\">\n <i [class]=\"item.icon\"></i> <span>{{ item.label }}</span>\n </button>\n }\n }\n </aside>\n\n <section class=\"ps-content\" [class.fill]=\"activeSection === 'registry'\" [attr.data-testid]=\"'ps-panel-' + activeSection\">\n @switch (activeSection) {\n @case ('registry') { <ps-registry [engine]=\"engine\" [provider]=\"ProviderToUse\" [currentUser]=\"ProviderToUse.CurrentUser\"></ps-registry> }\n @case ('production') { <ps-production [engine]=\"engine\"></ps-production> }\n }\n </section>\n </div>\n }\n </mj-page-body-interior>\n `,\n styles: [\n `\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-models-host { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .ps-leftnav { width: 210px; flex: none; border-right: 1px solid var(--mj-border-default); background: var(--mj-bg-surface-card); overflow-y: auto; padding: 10px 8px; display: flex; flex-direction: column; gap: 2px; }\n .ps-nav-group { font-size: var(--mj-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--mj-text-muted); padding: 12px 10px 4px; }\n .ps-nav-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 8px 10px; border: none; background: transparent; border-radius: var(--mj-radius-md); cursor: pointer; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); font-weight: 500; transition: background .12s, color .12s; }\n .ps-nav-item i { width: 18px; text-align: center; color: var(--mj-text-muted); }\n .ps-nav-item:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .ps-nav-item.active { background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); color: var(--mj-brand-primary); font-weight: 600; }\n .ps-nav-item.active i { color: var(--mj-brand-primary); }\n .ps-content { flex: 1; min-width: 0; overflow-y: auto; padding: 8px 14px 24px; }\n /* Fill mode (registry): the section stops page-scrolling so the panel's inner\n columns (model list / detail) can each own their scrollbar. */\n .ps-content.fill { overflow: hidden; display: flex; flex-direction: column; padding-bottom: 14px; }\n .ps-content.fill > * { flex: 1; min-height: 0; display: flex; flex-direction: column; }\n .ps-load-error { display: flex; align-items: center; gap: 14px; max-width: 620px; margin: 32px auto; padding: 18px 20px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-lg); }\n .ps-load-error > i { font-size: 24px; color: var(--mj-status-error); }\n .ps-load-error-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n .ps-load-error-text strong { color: var(--mj-text-primary); }\n .ps-load-error-detail { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); word-break: break-word; }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PSModelsResourceComponent extends PSResourceBase {\n protected readonly SectionKey = 'models';\n protected readonly SectionLabel = 'Models';\n protected readonly SectionIcon = 'fa-solid fa-cubes';\n\n private readonly cdrLocal = inject(ChangeDetectorRef);\n\n public activeSection: PSPanelKey = 'registry';\n public readonly sections: readonly PSSection[] = MODELS_SECTIONS;\n\n override ngOnInit(): void {\n super.ngOnInit();\n const initial = this.GetQueryParams()['section'] as PSPanelKey | undefined;\n if (initial && hasSection(this.sections, initial)) this.activeSection = initial;\n }\n\n protected override OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void {\n const next = params['section'] as PSPanelKey | undefined;\n if (next && next !== this.activeSection && hasSection(this.sections, next)) {\n this.activeSection = next;\n this.cdrLocal.detectChanges();\n }\n }\n\n /** Deep agent context for the Models door: active section + trained-model lifecycle counts. */\n protected override extraAgentContext(): Record<string, unknown> {\n const models = this.engine.Models;\n return buildModelsAgentContext({\n ActiveSection: this.activeSection,\n ActiveSectionLabel: this.activeLabel,\n SectionLabels: this.sections.map((s) => s.label),\n TotalModelCount: models.length,\n PublishedModelCount: this.engine.PublishedModels.length,\n DraftModelCount: models.filter((m) => m.Status === 'Draft').length,\n ProductionModelCount: models.filter((m) => this.engine.RecordProcessIDsForModel(m.ID).length > 0).length,\n });\n }\n\n /**\n * 🔒 Read/navigate-only agent tool for the Models door: switch the active section (Model Registry ↔\n * Models in Production). NO promote/retire/delete/score tool is exposed — model lifecycle changes stay\n * behind the user's own clicks.\n */\n protected override registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'SwitchModelsSection',\n Description: 'Switch the Models door to a section. Pass the section key or label (see SectionLabels): Model Registry or Models in Production.',\n ParameterSchema: { type: 'object', properties: { section: { type: 'string', description: 'The section key or label to switch to' } } },\n Handler: async (params: Record<string, unknown>) => {\n const check = validateStringParam(params['section'], 'section');\n if (!check.ok) return check.result;\n const candidates = this.sections.map((s) => ({ ID: s.key, Name: s.label }));\n const match = resolvePSRecord(check.value, candidates);\n if (!match) return { Success: false, ErrorMessage: buildPSNotFoundError(check.value, candidates, 'section') };\n this.selectSection(match.ID as PSPanelKey);\n return { Success: true, Data: { activeSection: match.Name } };\n },\n },\n ]);\n }\n\n public get groups(): string[] { return sectionGroups(this.sections); }\n public itemsForGroup(group: string): PSSection[] { return sectionsInGroup(this.sections, group); }\n public get activeLabel(): string { return sectionLabel(this.sections, this.activeSection); }\n\n /** Section-specific subtitle for the interior header. */\n public get activeSubtitle(): string {\n const map: Record<string, string> = {\n registry: 'Versioned trained models, their metrics, and lineage.',\n production: \"What's scoring live, and its recent runs.\",\n };\n return map[this.activeSection] ?? '';\n }\n\n public selectSection(key: PSPanelKey): void {\n if (this.activeSection === key) return;\n this.activeSection = key;\n this.UpdateQueryParams({ section: key });\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n}\n\n/** Tree-shaking prevention — called from the subpath module so the @RegisterClass survives bundling. */\nexport function LoadPSModelsResource(): void {\n // intentionally empty\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ps-models-resource.component.js","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-models-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { PSResourceBase } from './ps-resource-base';\nimport { PSPanelKey } from '../predictive-studio.types';\nimport { MODELS_SECTIONS, PSSection, sectionGroups, sectionsInGroup, sectionLabel, hasSection } from '../predictive-studio.nav';\nimport { buildModelsAgentContext, resolvePSRecord, buildPSNotFoundError } from '../predictive-studio-agent-context';\nimport { validateStringParam } from '../../shared/agent-tool-validation';\n\n/**\n * **Models** — the trained-model lifecycle door (one of Predictive Studio's three consolidated nav\n * items, alongside `Predictions` and `Studio`). Hosts the registry + production section panels\n * (`ps-registry`, `ps-production`) behind an internal left-nav. The active section round-trips through\n * the `section` query param, so the `Overview` panel's cross-door \"view in production\" links (and any\n * deep link) can land directly on the right section. No docked copilot here — these are read/manage\n * surfaces; model creation + the Model Dev Agent live in the `Studio` and `Predictions` doors.\n */\n@RegisterClass(BaseResourceComponent, 'PredictiveStudioModelsResource')\n@Component({\n standalone: false,\n selector: 'mj-ps-models-resource',\n template: `\n <mj-page-header-interior [Title]=\"activeLabel\" [Subtitle]=\"activeSubtitle\">\n </mj-page-header-interior>\n <mj-page-body-interior [Flex]=\"true\" [Padding]=\"false\">\n @if (isLoading) {\n <mj-loading text=\"Loading Models…\" size=\"medium\"></mj-loading>\n } @else if (loadError) {\n <div class=\"ps-load-error\" data-testid=\"ps-load-error\" role=\"alert\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div class=\"ps-load-error-text\">\n <strong>Couldn't load {{ sectionTitle }}</strong>\n <span class=\"ps-load-error-detail\">{{ loadError }}</span>\n </div>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"retryLoad()\"><i class=\"fa-solid fa-rotate-right\"></i> Try again</button>\n </div>\n } @else {\n <div class=\"ps-models-host\" [class.nav-collapsed]=\"isNavCollapsed\" data-testid=\"ps-models-shell\">\n @if (isNavCollapsed) {\n <div class=\"ps-nav-collapsed-strip\" role=\"region\" aria-label=\"Models navigation (collapsed)\">\n <button class=\"ps-nav-rail-collapse\" type=\"button\" (click)=\"toggleNav()\" aria-label=\"Expand models navigation\" title=\"Expand navigation\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n <div class=\"ps-nav-collapsed-strip-label\"><i class=\"fa-solid fa-cubes\"></i> Models</div>\n </div>\n }\n\n <as-split direction=\"horizontal\" class=\"models-splitter\" unit=\"percent\" [gutterSize]=\"isNavCollapsed ? 0 : 6\" (dragEnd)=\"onSplitDragEnd($event.sizes)\">\n @if (!isNavCollapsed) {\n <as-split-area [size]=\"navSizePct\" [minSize]=\"10\" [maxSize]=\"30\">\n <aside class=\"ps-leftnav\">\n <div class=\"ps-leftnav-header\">\n <span class=\"ps-leftnav-title\">Lifecycle</span>\n <button class=\"ps-leftnav-collapse-btn\" type=\"button\" (click)=\"toggleNav()\" title=\"Collapse navigation\" aria-label=\"Collapse navigation\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n </button>\n </div>\n @for (group of groups; track group) {\n @if (group) { <div class=\"ps-nav-group\">{{ group }}</div> }\n @for (item of itemsForGroup(group); track item.key) {\n <button class=\"ps-nav-item\" [class.active]=\"activeSection === item.key\"\n [attr.data-testid]=\"'ps-nav-' + item.key\" (click)=\"selectSection(item.key)\">\n <i [class]=\"item.icon\"></i> <span>{{ item.label }}</span>\n </button>\n }\n }\n </aside>\n </as-split-area>\n }\n\n <as-split-area [size]=\"isNavCollapsed ? 100 : contentSizePct\" [minSize]=\"50\">\n <section class=\"ps-content\" [class.fill]=\"activeSection === 'registry' || activeSection === 'production'\" [attr.data-testid]=\"'ps-panel-' + activeSection\">\n @switch (activeSection) {\n @case ('registry') { <ps-registry [engine]=\"engine\" [provider]=\"ProviderToUse\" [currentUser]=\"ProviderToUse.CurrentUser\" [initialModelId]=\"initialModelId\"></ps-registry> }\n @case ('production') { <ps-production [engine]=\"engine\"></ps-production> }\n }\n </section>\n </as-split-area>\n </as-split>\n </div>\n }\n </mj-page-body-interior>\n `,\n styles: [\n `\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-models-host { display: flex; flex: 1; min-height: 0; overflow: hidden; width: 100%; height: 100%; }\n .models-splitter { flex: 1; width: 100%; height: 100%; min-height: 0; min-width: 0; background: transparent; }\n .models-splitter .as-split-gutter { background: transparent; transition: background-color 0.15s ease; position: relative; }\n .models-splitter .as-split-gutter:hover { background-color: var(--mj-brand-primary, #6366f1); }\n .models-splitter .as-split-gutter::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 2px; height: 24px; border-radius: 1px; background: var(--mj-border-strong, #cbd5e1); }\n .models-splitter .as-split-gutter:hover::after { background: #ffffff; }\n\n .ps-nav-collapsed-strip { width: 44px; min-width: 44px; max-width: 44px; flex: none; background: var(--mj-bg-surface); border-right: 1px solid var(--mj-border-default); display: flex; flex-direction: column; align-items: center; padding: 10px 0; gap: 14px; z-index: 2; }\n .ps-nav-rail-collapse { background: var(--mj-bg-surface-subtle); border: 1px solid var(--mj-border-default); border-radius: 6px; color: var(--mj-text-secondary); cursor: pointer; display: grid; place-items: center; width: 28px; height: 28px; padding: 0; font-size: 11px; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease; }\n .ps-nav-rail-collapse:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); border-color: var(--mj-border-strong); }\n .ps-nav-collapsed-strip-label { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; color: var(--mj-text-muted); display: flex; align-items: center; gap: 8px; text-transform: uppercase; }\n\n .ps-leftnav { width: 100%; height: 100%; border-right: 1px solid var(--mj-border-default); background: var(--mj-bg-surface-card); overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 2px; box-sizing: border-box; }\n .ps-leftnav-header { display: flex; align-items: center; justify-content: space-between; padding: 4px 6px 8px; border-bottom: 1px solid var(--mj-border-subtle); margin-bottom: 4px; }\n .ps-leftnav-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--mj-text-muted); }\n .ps-leftnav-collapse-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 6px; border: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); color: var(--mj-text-muted); cursor: pointer; transition: all 0.15s ease; padding: 0; }\n .ps-leftnav-collapse-btn:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); border-color: var(--mj-border-strong); }\n\n .ps-nav-group { font-size: var(--mj-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--mj-text-muted); padding: 10px 8px 4px; }\n .ps-nav-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 8px 10px; border: none; background: transparent; border-radius: var(--mj-radius-md); cursor: pointer; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); font-weight: 500; transition: background .12s, color .12s; }\n .ps-nav-item i { width: 18px; text-align: center; color: var(--mj-text-muted); }\n .ps-nav-item:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .ps-nav-item.active { background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); color: var(--mj-brand-primary); font-weight: 600; }\n .ps-nav-item.active i { color: var(--mj-brand-primary); }\n .ps-content { width: 100%; height: 100%; flex: 1; min-width: 0; overflow-y: auto; padding: 8px 14px 24px; }\n /* Fill mode (registry): the section stops page-scrolling so the panel's inner\n columns (model list / detail) can each own their scrollbar. */\n .ps-content.fill { overflow: hidden; display: flex; flex-direction: column; padding-bottom: 14px; }\n .ps-content.fill > * { flex: 1; min-height: 0; display: flex; flex-direction: column; }\n .ps-load-error { display: flex; align-items: center; gap: 14px; max-width: 620px; margin: 32px auto; padding: 18px 20px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-lg); }\n .ps-load-error > i { font-size: 24px; color: var(--mj-status-error); }\n .ps-load-error-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n .ps-load-error-text strong { color: var(--mj-text-primary); }\n .ps-load-error-detail { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); word-break: break-word; }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PSModelsResourceComponent extends PSResourceBase {\n protected readonly SectionKey = 'models';\n protected readonly SectionLabel = 'Models';\n protected readonly SectionIcon = 'fa-solid fa-cubes';\n\n private readonly cdrLocal = inject(ChangeDetectorRef);\n\n public activeSection: PSPanelKey = 'registry';\n public readonly sections: readonly PSSection[] = MODELS_SECTIONS;\n public initialModelId?: string;\n public isNavCollapsed = false;\n public navSizePct = 14;\n public contentSizePct = 86;\n\n override ngOnInit(): void {\n super.ngOnInit();\n const qp = this.GetQueryParams();\n const initial = qp['section'] as PSPanelKey | undefined;\n if (initial && hasSection(this.sections, initial)) this.activeSection = initial;\n if (qp['modelId']) this.initialModelId = qp['modelId'];\n this.loadLayoutPrefs();\n }\n\n public toggleNav(): void {\n this.isNavCollapsed = !this.isNavCollapsed;\n this.saveLayoutPrefs();\n this.cdrLocal.detectChanges();\n }\n\n public onSplitDragEnd(sizes: readonly (number | '*')[]): void {\n if (Array.isArray(sizes) && sizes.length === 2 && typeof sizes[0] === 'number' && typeof sizes[1] === 'number') {\n this.navSizePct = Math.round(sizes[0]);\n this.contentSizePct = Math.round(sizes[1]);\n this.saveLayoutPrefs();\n }\n }\n\n private loadLayoutPrefs(): void {\n const raw = UserInfoEngine.Instance.GetSetting('mj.predictiveStudio.models.layout');\n if (raw) {\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed.navSizePct === 'number' && parsed.navSizePct >= 10 && parsed.navSizePct <= 35) {\n this.navSizePct = parsed.navSizePct;\n this.contentSizePct = 100 - parsed.navSizePct;\n }\n if (typeof parsed.isNavCollapsed === 'boolean') {\n this.isNavCollapsed = parsed.isNavCollapsed;\n }\n } catch {}\n }\n }\n\n private saveLayoutPrefs(): void {\n const prefs = {\n navSizePct: this.navSizePct,\n contentSizePct: this.contentSizePct,\n isNavCollapsed: this.isNavCollapsed,\n };\n UserInfoEngine.Instance.SetSettingDebounced('mj.predictiveStudio.models.layout', JSON.stringify(prefs));\n }\n\n protected override async OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): Promise<void> {\n const next = params['section'] as PSPanelKey | undefined;\n if (next && next !== this.activeSection && hasSection(this.sections, next)) {\n this.activeSection = next;\n }\n if (params['modelId']) {\n this.initialModelId = params['modelId'];\n if (this.engine && !this.engine.Models.some((m) => UUIDsEqual(m.ID, params['modelId']))) {\n await this.engine.Config(true, this.ProviderToUse.CurrentUser ?? undefined, this.ProviderToUse);\n }\n }\n this.cdrLocal.detectChanges();\n }\n\n /** Deep agent context for the Models door: active section + trained-model lifecycle counts. */\n protected override extraAgentContext(): Record<string, unknown> {\n const models = this.engine.Models;\n return buildModelsAgentContext({\n ActiveSection: this.activeSection,\n ActiveSectionLabel: this.activeLabel,\n SectionLabels: this.sections.map((s) => s.label),\n TotalModelCount: models.length,\n PublishedModelCount: this.engine.PublishedModels.length,\n DraftModelCount: models.filter((m) => m.Status === 'Draft').length,\n ProductionModelCount: models.filter((m) => this.engine.RecordProcessIDsForModel(m.ID).length > 0).length,\n });\n }\n\n /**\n * 🔒 Read/navigate-only agent tool for the Models door: switch the active section (Model Registry ↔\n * Models in Production). NO promote/retire/delete/score tool is exposed — model lifecycle changes stay\n * behind the user's own clicks.\n */\n protected override registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'SwitchModelsSection',\n Description: 'Switch the Models door to a section. Pass the section key or label (see SectionLabels): Model Registry or Models in Production.',\n ParameterSchema: { type: 'object', properties: { section: { type: 'string', description: 'The section key or label to switch to' } } },\n Handler: async (params: Record<string, unknown>) => {\n const check = validateStringParam(params['section'], 'section');\n if (!check.ok) return check.result;\n const candidates = this.sections.map((s) => ({ ID: s.key, Name: s.label }));\n const match = resolvePSRecord(check.value, candidates);\n if (!match) return { Success: false, ErrorMessage: buildPSNotFoundError(check.value, candidates, 'section') };\n this.selectSection(match.ID as PSPanelKey);\n return { Success: true, Data: { activeSection: match.Name } };\n },\n },\n ]);\n }\n\n public get groups(): string[] { return sectionGroups(this.sections); }\n public itemsForGroup(group: string): PSSection[] { return sectionsInGroup(this.sections, group); }\n public get activeLabel(): string { return sectionLabel(this.sections, this.activeSection); }\n\n /** Section-specific subtitle for the interior header. */\n public get activeSubtitle(): string {\n const map: Record<string, string> = {\n registry: 'Versioned trained models, their metrics, and lineage.',\n production: \"What's scoring live, and its recent runs.\",\n };\n return map[this.activeSection] ?? '';\n }\n\n public selectSection(key: PSPanelKey): void {\n if (this.activeSection === key) return;\n this.activeSection = key;\n this.UpdateQueryParams({ section: key });\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n}\n\n/** Tree-shaking prevention — called from the subpath module so the @RegisterClass survives bundling. */\nexport function LoadPSModelsResource(): void {\n // intentionally empty\n}\n"]}
|
|
@@ -33,6 +33,12 @@ export declare class PSPredictionsResourceComponent extends PSResourceBase {
|
|
|
33
33
|
chatConversation: MJConversationEntity | null;
|
|
34
34
|
chatConversationId: string | null;
|
|
35
35
|
chatIsNewConversation: boolean;
|
|
36
|
+
mainSizePct: number;
|
|
37
|
+
copilotSizePct: number;
|
|
38
|
+
ngOnInit(): void;
|
|
39
|
+
onCopilotSplitDragEnd(sizes: readonly (number | '*')[]): void;
|
|
40
|
+
private loadLayoutPrefs;
|
|
41
|
+
private saveLayoutPrefs;
|
|
36
42
|
/** The ranked at-risk rows for the open prediction's latest run (empty until loaded / when no run yet). */
|
|
37
43
|
atRiskRows: AtRiskRow[];
|
|
38
44
|
/** Plain-language "what's driving this" drivers for the open prediction (global feature importance). */
|
|
@@ -44,6 +50,7 @@ export declare class PSPredictionsResourceComponent extends PSResourceBase {
|
|
|
44
50
|
/** "Send to a list" in-flight guard + last-result message (P1 #4). */
|
|
45
51
|
creatingList: boolean;
|
|
46
52
|
listResult: string | null;
|
|
53
|
+
latestRunId: string | null;
|
|
47
54
|
/** Capability cards for the first-run intro (what PS can do), shown when the catalog is empty. */
|
|
48
55
|
readonly capabilityCards: readonly PSCapabilityCard[];
|
|
49
56
|
/** The business catalog cards, most-trustworthy first, derived from the engine's published models. */
|
|
@@ -70,7 +77,8 @@ export declare class PSPredictionsResourceComponent extends PSResourceBase {
|
|
|
70
77
|
* model's target entity, so the list reads like a call sheet instead of a column of UUIDs. Resolves the
|
|
71
78
|
* top-risk rows (capped) to keep the lookup light; unresolved rows fall back to their id in the template.
|
|
72
79
|
*/
|
|
73
|
-
|
|
80
|
+
get selectedTargetEntityName(): string | null;
|
|
81
|
+
get selectedProblemType(): string | null;
|
|
74
82
|
private targetEntityForModel;
|
|
75
83
|
private resolveAtRiskLabels;
|
|
76
84
|
backToCatalog(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ps-predictions-resource.component.d.ts","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-predictions-resource.component.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmC,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"ps-predictions-resource.component.d.ts","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-predictions-resource.component.ts"],"names":[],"mappings":"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"}
|