@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
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import { ChangeDetectorRef, Component, Input, ViewEncapsulation, inject } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { AngularSplitModule } from 'angular-split';
|
|
3
4
|
import { SharedGenericModule } from '@memberjunction/ng-shared-generic';
|
|
4
5
|
import { MJButtonDirective } from '@memberjunction/ng-ui-components';
|
|
5
6
|
import { RunView } from '@memberjunction/core';
|
|
6
7
|
import { UUIDsEqual } from '@memberjunction/global';
|
|
8
|
+
import { UserInfoEngine } from '@memberjunction/core-entities';
|
|
7
9
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
8
|
-
import {
|
|
10
|
+
import { primaryModelScore, formatMetricValue } from '../predictive-studio.view-models';
|
|
9
11
|
import { humanizeCron } from '../production-distribution';
|
|
10
12
|
import { PSOperateDialogComponent } from './ps-operate-dialog.component';
|
|
13
|
+
import { PSPredictionsGridComponent } from './ps-predictions-grid.component';
|
|
11
14
|
import * as i0 from "@angular/core";
|
|
12
|
-
import * as i1 from "
|
|
13
|
-
import * as i2 from "@
|
|
15
|
+
import * as i1 from "angular-split";
|
|
16
|
+
import * as i2 from "@memberjunction/ng-shared-generic";
|
|
17
|
+
import * as i3 from "@angular/common";
|
|
14
18
|
const _forTrack0 = ($index, $item) => $item.modelId;
|
|
15
19
|
const _forTrack1 = ($index, $item) => $item.id;
|
|
16
|
-
const _forTrack2 = ($index, $item) => $item.
|
|
17
|
-
const _forTrack3 = ($index, $item) => $item.ID;
|
|
20
|
+
const _forTrack2 = ($index, $item) => $item.ID;
|
|
18
21
|
function PSProductionComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
19
22
|
i0.ɵɵelementStart(0, "div", 1)(1, "span", 2);
|
|
20
23
|
i0.ɵɵelement(2, "i", 3);
|
|
@@ -26,48 +29,213 @@ function PSProductionComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
|
26
29
|
i0.ɵɵtext(6, " When you publish a trained model in the Model Registry it shows up here \u2014 ready to schedule, bind to a column, and run. Train a pipeline and promote the model to Published to get started. ");
|
|
27
30
|
i0.ɵɵelementEnd()();
|
|
28
31
|
} }
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
i0.ɵɵ
|
|
32
|
-
i0.ɵɵ
|
|
33
|
-
i0.ɵɵelementStart(
|
|
32
|
+
function PSProductionComponent_Conditional_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
33
|
+
i0.ɵɵelementStart(0, "div", 4)(1, "div", 32)(2, "div", 33);
|
|
34
|
+
i0.ɵɵtext(3, "Published");
|
|
35
|
+
i0.ɵɵelementEnd();
|
|
36
|
+
i0.ɵɵelementStart(4, "div", 34);
|
|
37
|
+
i0.ɵɵtext(5);
|
|
38
|
+
i0.ɵɵelementEnd()();
|
|
39
|
+
i0.ɵɵelementStart(6, "div", 32)(7, "div", 33);
|
|
40
|
+
i0.ɵɵtext(8, "Scheduled");
|
|
41
|
+
i0.ɵɵelementEnd();
|
|
42
|
+
i0.ɵɵelementStart(9, "div", 34);
|
|
43
|
+
i0.ɵɵtext(10);
|
|
44
|
+
i0.ɵɵelementEnd()();
|
|
45
|
+
i0.ɵɵelementStart(11, "div", 32)(12, "div", 33);
|
|
46
|
+
i0.ɵɵtext(13, "Bound (write-back)");
|
|
47
|
+
i0.ɵɵelementEnd();
|
|
48
|
+
i0.ɵɵelementStart(14, "div", 34);
|
|
49
|
+
i0.ɵɵtext(15);
|
|
50
|
+
i0.ɵɵelementEnd()();
|
|
51
|
+
i0.ɵɵelementStart(16, "div", 32)(17, "div", 33);
|
|
52
|
+
i0.ɵɵtext(18, "Idle");
|
|
53
|
+
i0.ɵɵelementEnd();
|
|
54
|
+
i0.ɵɵelementStart(19, "div", 34);
|
|
55
|
+
i0.ɵɵtext(20);
|
|
56
|
+
i0.ɵɵelementEnd()()();
|
|
57
|
+
} if (rf & 2) {
|
|
58
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
59
|
+
i0.ɵɵadvance(5);
|
|
60
|
+
i0.ɵɵtextInterpolate(ctx_r1.models.length);
|
|
61
|
+
i0.ɵɵadvance(5);
|
|
62
|
+
i0.ɵɵtextInterpolate(ctx_r1.scheduledModelCount);
|
|
63
|
+
i0.ɵɵadvance(5);
|
|
64
|
+
i0.ɵɵtextInterpolate(ctx_r1.boundModelCount);
|
|
65
|
+
i0.ɵɵadvance(5);
|
|
66
|
+
i0.ɵɵtextInterpolate(ctx_r1.idleModelCount);
|
|
67
|
+
} }
|
|
68
|
+
function PSProductionComponent_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
69
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
70
|
+
i0.ɵɵelementStart(0, "div", 6)(1, "button", 35);
|
|
71
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_2_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleList()); });
|
|
72
|
+
i0.ɵɵelement(2, "i", 36);
|
|
73
|
+
i0.ɵɵelementEnd();
|
|
74
|
+
i0.ɵɵelementStart(3, "div", 37);
|
|
75
|
+
i0.ɵɵelement(4, "i", 3);
|
|
76
|
+
i0.ɵɵelementEnd()();
|
|
77
|
+
} }
|
|
78
|
+
function PSProductionComponent_Conditional_2_Conditional_4_For_12_Template(rf, ctx) { if (rf & 1) {
|
|
79
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
80
|
+
i0.ɵɵelementStart(0, "div", 45);
|
|
81
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_4_For_12_Template_div_click_0_listener() { const m_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.select(m_r6.modelId)); });
|
|
82
|
+
i0.ɵɵelementStart(1, "div", 46);
|
|
34
83
|
i0.ɵɵelement(2, "i");
|
|
35
84
|
i0.ɵɵelementEnd();
|
|
36
|
-
i0.ɵɵelementStart(3, "div",
|
|
85
|
+
i0.ɵɵelementStart(3, "div", 47)(4, "div", 48);
|
|
37
86
|
i0.ɵɵtext(5);
|
|
38
87
|
i0.ɵɵelementEnd();
|
|
39
|
-
i0.ɵɵelementStart(6, "div",
|
|
88
|
+
i0.ɵɵelementStart(6, "div", 49);
|
|
40
89
|
i0.ɵɵtext(7);
|
|
41
90
|
i0.ɵɵelementEnd()();
|
|
42
|
-
i0.ɵɵelementStart(8, "div",
|
|
91
|
+
i0.ɵɵelementStart(8, "div", 50)(9, "span", 51);
|
|
43
92
|
i0.ɵɵtext(10);
|
|
44
93
|
i0.ɵɵelementEnd();
|
|
45
|
-
i0.ɵɵelementStart(11, "div",
|
|
94
|
+
i0.ɵɵelementStart(11, "div", 52);
|
|
46
95
|
i0.ɵɵtext(12);
|
|
47
96
|
i0.ɵɵelementEnd()()();
|
|
48
97
|
} if (rf & 2) {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
i0.ɵɵclassProp("sel",
|
|
98
|
+
const m_r6 = ctx.$implicit;
|
|
99
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
100
|
+
i0.ɵɵclassProp("sel", m_r6.modelId === ctx_r1.selectedModelId);
|
|
52
101
|
i0.ɵɵadvance();
|
|
53
|
-
i0.ɵɵclassMap("st-" +
|
|
102
|
+
i0.ɵɵclassMap("st-" + m_r6.deployState);
|
|
54
103
|
i0.ɵɵadvance();
|
|
55
|
-
i0.ɵɵclassMap(
|
|
104
|
+
i0.ɵɵclassMap(ctx_r1.deployIcon(m_r6.deployState));
|
|
56
105
|
i0.ɵɵadvance(3);
|
|
57
|
-
i0.ɵɵtextInterpolate(
|
|
106
|
+
i0.ɵɵtextInterpolate(m_r6.label);
|
|
58
107
|
i0.ɵɵadvance(2);
|
|
59
|
-
i0.ɵɵtextInterpolate2("v",
|
|
108
|
+
i0.ɵɵtextInterpolate2("v", m_r6.version, " \u00B7 ", m_r6.algorithm);
|
|
60
109
|
i0.ɵɵadvance(2);
|
|
61
|
-
i0.ɵɵclassMap(
|
|
110
|
+
i0.ɵɵclassMap(ctx_r1.deployBadge(m_r6.deployState));
|
|
111
|
+
i0.ɵɵadvance();
|
|
112
|
+
i0.ɵɵtextInterpolate(ctx_r1.deployLabel(m_r6.deployState));
|
|
113
|
+
i0.ɵɵadvance(2);
|
|
114
|
+
i0.ɵɵtextInterpolate(m_r6.holdoutMetric);
|
|
115
|
+
} }
|
|
116
|
+
function PSProductionComponent_Conditional_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
117
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
118
|
+
i0.ɵɵelementStart(0, "as-split-area", 8)(1, "div", 38)(2, "div", 25)(3, "h3");
|
|
119
|
+
i0.ɵɵtext(4, "Published models");
|
|
120
|
+
i0.ɵɵelementEnd();
|
|
121
|
+
i0.ɵɵelementStart(5, "div", 39)(6, "span", 40);
|
|
122
|
+
i0.ɵɵtext(7);
|
|
123
|
+
i0.ɵɵelementEnd();
|
|
124
|
+
i0.ɵɵelementStart(8, "button", 41);
|
|
125
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_4_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleList()); });
|
|
126
|
+
i0.ɵɵelement(9, "i", 42);
|
|
127
|
+
i0.ɵɵelementEnd()()();
|
|
128
|
+
i0.ɵɵelementStart(10, "div", 43);
|
|
129
|
+
i0.ɵɵrepeaterCreate(11, PSProductionComponent_Conditional_2_Conditional_4_For_12_Template, 13, 13, "div", 44, _forTrack0);
|
|
130
|
+
i0.ɵɵelementEnd()()();
|
|
131
|
+
} if (rf & 2) {
|
|
132
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
133
|
+
i0.ɵɵproperty("size", ctx_r1.listSizePct)("minSize", 18)("maxSize", 50);
|
|
134
|
+
i0.ɵɵadvance(7);
|
|
135
|
+
i0.ɵɵtextInterpolate(ctx_r1.models.length);
|
|
136
|
+
i0.ɵɵadvance(4);
|
|
137
|
+
i0.ɵɵrepeater(ctx_r1.models);
|
|
138
|
+
} }
|
|
139
|
+
function PSProductionComponent_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
140
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
141
|
+
i0.ɵɵelementStart(0, "div", 12)(1, "div", 53);
|
|
142
|
+
i0.ɵɵelement(2, "i");
|
|
143
|
+
i0.ɵɵelementEnd();
|
|
144
|
+
i0.ɵɵelementStart(3, "div", 47)(4, "h2", 54);
|
|
145
|
+
i0.ɵɵtext(5);
|
|
146
|
+
i0.ɵɵelementStart(6, "span", 55);
|
|
147
|
+
i0.ɵɵtext(7);
|
|
148
|
+
i0.ɵɵelementEnd()();
|
|
149
|
+
i0.ɵɵelementStart(8, "div", 56);
|
|
150
|
+
i0.ɵɵtext(9);
|
|
151
|
+
i0.ɵɵelementEnd()();
|
|
152
|
+
i0.ɵɵelementStart(10, "span", 51);
|
|
153
|
+
i0.ɵɵtext(11);
|
|
154
|
+
i0.ɵɵelementEnd();
|
|
155
|
+
i0.ɵɵelementStart(12, "button", 57);
|
|
156
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_8_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.operateOpen = true); });
|
|
157
|
+
i0.ɵɵelement(13, "i", 58);
|
|
158
|
+
i0.ɵɵtext(14, " Operate ");
|
|
159
|
+
i0.ɵɵelementEnd();
|
|
160
|
+
i0.ɵɵelementStart(15, "button", 59);
|
|
161
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_8_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleHeaderCollapse()); });
|
|
162
|
+
i0.ɵɵelement(16, "i", 60);
|
|
163
|
+
i0.ɵɵelementEnd()();
|
|
164
|
+
} if (rf & 2) {
|
|
165
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
166
|
+
i0.ɵɵadvance();
|
|
167
|
+
i0.ɵɵclassMap("st-" + ctx_r1.selected.deployState);
|
|
62
168
|
i0.ɵɵadvance();
|
|
63
|
-
i0.ɵɵ
|
|
169
|
+
i0.ɵɵclassMap(ctx_r1.deployIcon(ctx_r1.selected.deployState));
|
|
170
|
+
i0.ɵɵadvance(3);
|
|
171
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.selected.label, " ");
|
|
64
172
|
i0.ɵɵadvance(2);
|
|
65
|
-
i0.ɵɵ
|
|
173
|
+
i0.ɵɵtextInterpolate1("v", ctx_r1.selected.version);
|
|
174
|
+
i0.ɵɵadvance(2);
|
|
175
|
+
i0.ɵɵtextInterpolate3("", ctx_r1.selected.algorithm, " \u00B7 ", ctx_r1.selected.problemType, " \u00B7 holdout ", ctx_r1.selected.holdoutMetric);
|
|
176
|
+
i0.ɵɵadvance();
|
|
177
|
+
i0.ɵɵclassMap(ctx_r1.deployBadge(ctx_r1.selected.deployState));
|
|
178
|
+
i0.ɵɵadvance();
|
|
179
|
+
i0.ɵɵtextInterpolate(ctx_r1.deployLabel(ctx_r1.selected.deployState));
|
|
66
180
|
} }
|
|
67
|
-
function
|
|
68
|
-
i0.ɵɵ
|
|
69
|
-
i0.ɵɵ
|
|
70
|
-
i0.ɵɵ
|
|
181
|
+
function PSProductionComponent_Conditional_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
182
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
183
|
+
i0.ɵɵelementStart(0, "div", 61);
|
|
184
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_9_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleHeaderCollapse()); });
|
|
185
|
+
i0.ɵɵelementStart(1, "div", 62);
|
|
186
|
+
i0.ɵɵelement(2, "i");
|
|
187
|
+
i0.ɵɵelementEnd();
|
|
188
|
+
i0.ɵɵelementStart(3, "div", 63)(4, "strong");
|
|
189
|
+
i0.ɵɵtext(5);
|
|
190
|
+
i0.ɵɵelementEnd();
|
|
191
|
+
i0.ɵɵelementStart(6, "span", 64);
|
|
192
|
+
i0.ɵɵtext(7);
|
|
193
|
+
i0.ɵɵelementEnd();
|
|
194
|
+
i0.ɵɵelementStart(8, "span", 18);
|
|
195
|
+
i0.ɵɵtext(9);
|
|
196
|
+
i0.ɵɵelementEnd()();
|
|
197
|
+
i0.ɵɵelementStart(10, "span", 51);
|
|
198
|
+
i0.ɵɵtext(11);
|
|
199
|
+
i0.ɵɵelementEnd();
|
|
200
|
+
i0.ɵɵelementStart(12, "button", 65);
|
|
201
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_9_Template_button_click_12_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); $event.stopPropagation(); return i0.ɵɵresetView(ctx_r1.operateOpen = true); });
|
|
202
|
+
i0.ɵɵelement(13, "i", 58);
|
|
203
|
+
i0.ɵɵtext(14, " Operate ");
|
|
204
|
+
i0.ɵɵelementEnd();
|
|
205
|
+
i0.ɵɵelementStart(15, "button", 66);
|
|
206
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_9_Template_button_click_15_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); $event.stopPropagation(); return i0.ɵɵresetView(ctx_r1.toggleHeaderCollapse()); });
|
|
207
|
+
i0.ɵɵelement(16, "i", 67);
|
|
208
|
+
i0.ɵɵelementEnd()();
|
|
209
|
+
} if (rf & 2) {
|
|
210
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
211
|
+
i0.ɵɵadvance();
|
|
212
|
+
i0.ɵɵclassMap("st-" + ctx_r1.selected.deployState);
|
|
213
|
+
i0.ɵɵadvance();
|
|
214
|
+
i0.ɵɵclassMap(ctx_r1.deployIcon(ctx_r1.selected.deployState));
|
|
215
|
+
i0.ɵɵadvance(3);
|
|
216
|
+
i0.ɵɵtextInterpolate(ctx_r1.selected.label);
|
|
217
|
+
i0.ɵɵadvance(2);
|
|
218
|
+
i0.ɵɵtextInterpolate1("v", ctx_r1.selected.version);
|
|
219
|
+
i0.ɵɵadvance(2);
|
|
220
|
+
i0.ɵɵtextInterpolate1("\u00B7 ", ctx_r1.selected.algorithm);
|
|
221
|
+
i0.ɵɵadvance();
|
|
222
|
+
i0.ɵɵclassMap(ctx_r1.deployBadge(ctx_r1.selected.deployState));
|
|
223
|
+
i0.ɵɵadvance();
|
|
224
|
+
i0.ɵɵtextInterpolate(ctx_r1.deployLabel(ctx_r1.selected.deployState));
|
|
225
|
+
} }
|
|
226
|
+
function PSProductionComponent_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
227
|
+
i0.ɵɵelementStart(0, "span", 19);
|
|
228
|
+
i0.ɵɵtext(1);
|
|
229
|
+
i0.ɵɵelementEnd();
|
|
230
|
+
} if (rf & 2) {
|
|
231
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
232
|
+
i0.ɵɵadvance();
|
|
233
|
+
i0.ɵɵtextInterpolate2("", ctx_r1.selectedBindings[0].targetEntity, ".", ctx_r1.selectedBindings[0].targetColumn);
|
|
234
|
+
} }
|
|
235
|
+
function PSProductionComponent_Conditional_2_Conditional_22_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
236
|
+
i0.ɵɵelementStart(0, "div", 68);
|
|
237
|
+
i0.ɵɵelement(1, "i", 69);
|
|
238
|
+
i0.ɵɵelementStart(2, "div", 70);
|
|
71
239
|
i0.ɵɵtext(3, "This model is published but ");
|
|
72
240
|
i0.ɵɵelementStart(4, "strong");
|
|
73
241
|
i0.ɵɵtext(5, "not operating");
|
|
@@ -79,209 +247,172 @@ function PSProductionComponent_Conditional_2_Conditional_55_Template(rf, ctx) {
|
|
|
79
247
|
i0.ɵɵtext(9, " above to run it now, schedule it to run regularly, or write predictions back to a column.");
|
|
80
248
|
i0.ɵɵelementEnd()();
|
|
81
249
|
} }
|
|
82
|
-
function
|
|
83
|
-
i0.ɵɵelementStart(0, "div",
|
|
84
|
-
i0.ɵɵelement(1, "i",
|
|
85
|
-
i0.ɵɵelementStart(2, "div",
|
|
250
|
+
function PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Conditional_0_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
251
|
+
i0.ɵɵelementStart(0, "div", 72);
|
|
252
|
+
i0.ɵɵelement(1, "i", 73);
|
|
253
|
+
i0.ɵɵelementStart(2, "div", 74)(3, "div", 70)(4, "strong");
|
|
86
254
|
i0.ɵɵtext(5);
|
|
87
255
|
i0.ɵɵelementEnd();
|
|
88
256
|
i0.ɵɵtext(6);
|
|
89
257
|
i0.ɵɵelementEnd();
|
|
90
|
-
i0.ɵɵelementStart(7, "div",
|
|
258
|
+
i0.ɵɵelementStart(7, "div", 18);
|
|
91
259
|
i0.ɵɵtext(8);
|
|
92
260
|
i0.ɵɵelementEnd()();
|
|
93
|
-
i0.ɵɵelementStart(9, "span",
|
|
261
|
+
i0.ɵɵelementStart(9, "span", 51);
|
|
94
262
|
i0.ɵɵtext(10);
|
|
95
263
|
i0.ɵɵelementEnd()();
|
|
96
264
|
} if (rf & 2) {
|
|
97
|
-
const
|
|
98
|
-
const
|
|
265
|
+
const b_r9 = ctx.$implicit;
|
|
266
|
+
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
99
267
|
i0.ɵɵadvance(5);
|
|
100
|
-
i0.ɵɵtextInterpolate(
|
|
268
|
+
i0.ɵɵtextInterpolate(b_r9.targetEntity);
|
|
101
269
|
i0.ɵɵadvance();
|
|
102
|
-
i0.ɵɵtextInterpolate1(".",
|
|
270
|
+
i0.ɵɵtextInterpolate1(".", b_r9.targetColumn);
|
|
103
271
|
i0.ɵɵadvance(2);
|
|
104
|
-
i0.ɵɵtextInterpolate2("",
|
|
272
|
+
i0.ɵɵtextInterpolate2("", b_r9.mode, "", b_r9.schedulePhrase ? " \u00B7 " + b_r9.schedulePhrase : "");
|
|
105
273
|
i0.ɵɵadvance();
|
|
106
|
-
i0.ɵɵclassMap(
|
|
274
|
+
i0.ɵɵclassMap(ctx_r1.modeBadge(b_r9.mode));
|
|
107
275
|
i0.ɵɵadvance();
|
|
108
|
-
i0.ɵɵtextInterpolate(
|
|
276
|
+
i0.ɵɵtextInterpolate(b_r9.mode);
|
|
109
277
|
} }
|
|
110
|
-
function
|
|
111
|
-
i0.ɵɵelementStart(0, "div",
|
|
278
|
+
function PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
279
|
+
i0.ɵɵelementStart(0, "div", 71);
|
|
112
280
|
i0.ɵɵtext(1, "Scoring bindings");
|
|
113
281
|
i0.ɵɵelementEnd();
|
|
114
|
-
i0.ɵɵrepeaterCreate(2,
|
|
282
|
+
i0.ɵɵrepeaterCreate(2, PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Conditional_0_For_3_Template, 11, 7, "div", 72, _forTrack1);
|
|
115
283
|
} if (rf & 2) {
|
|
116
|
-
const
|
|
284
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
117
285
|
i0.ɵɵadvance(2);
|
|
118
|
-
i0.ɵɵrepeater(
|
|
286
|
+
i0.ɵɵrepeater(ctx_r1.selectedBindings);
|
|
119
287
|
} }
|
|
120
|
-
function
|
|
288
|
+
function PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
121
289
|
i0.ɵɵelementStart(0, "div", 29);
|
|
122
290
|
i0.ɵɵtext(1, "Scheduled to run, writing generic output to the process run history (no write-back column).");
|
|
123
291
|
i0.ɵɵelementEnd();
|
|
124
292
|
} }
|
|
125
|
-
function
|
|
126
|
-
i0.ɵɵelement(0, "div",
|
|
127
|
-
i0.ɵɵelementStart(1, "div",
|
|
293
|
+
function PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
294
|
+
i0.ɵɵelement(0, "div", 75);
|
|
295
|
+
i0.ɵɵelementStart(1, "div", 76)(2, "span", 18);
|
|
128
296
|
i0.ɵɵtext(3, "Last scored");
|
|
129
297
|
i0.ɵɵelementEnd();
|
|
130
|
-
i0.ɵɵelementStart(4, "span",
|
|
298
|
+
i0.ɵɵelementStart(4, "span", 70);
|
|
131
299
|
i0.ɵɵtext(5);
|
|
132
300
|
i0.ɵɵpipe(6, "date");
|
|
133
301
|
i0.ɵɵelementEnd()();
|
|
134
302
|
} if (rf & 2) {
|
|
135
|
-
const
|
|
303
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
136
304
|
i0.ɵɵadvance(5);
|
|
137
|
-
i0.ɵɵtextInterpolate2("", i0.ɵɵpipeBind2(6, 2,
|
|
305
|
+
i0.ɵɵtextInterpolate2("", i0.ɵɵpipeBind2(6, 2, ctx_r1.selected.lastScoredAt, "medium"), "", ctx_r1.selected.lastRowCount != null ? " \u00B7 " + ctx_r1.selected.lastRowCount + " rows" : "");
|
|
138
306
|
} }
|
|
139
|
-
function
|
|
140
|
-
i0.ɵɵconditionalCreate(0,
|
|
141
|
-
i0.ɵɵconditionalCreate(2,
|
|
307
|
+
function PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
308
|
+
i0.ɵɵconditionalCreate(0, PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Conditional_0_Template, 4, 0)(1, PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Conditional_1_Template, 2, 0, "div", 29);
|
|
309
|
+
i0.ɵɵconditionalCreate(2, PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Conditional_2_Template, 7, 5);
|
|
142
310
|
} if (rf & 2) {
|
|
143
|
-
const
|
|
144
|
-
i0.ɵɵconditional(
|
|
311
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
312
|
+
i0.ɵɵconditional(ctx_r1.selectedBindings.length > 0 ? 0 : 1);
|
|
145
313
|
i0.ɵɵadvance(2);
|
|
146
|
-
i0.ɵɵconditional(
|
|
314
|
+
i0.ɵɵconditional(ctx_r1.selected.lastScoredAt ? 2 : -1);
|
|
147
315
|
} }
|
|
148
|
-
function
|
|
149
|
-
i0.ɵɵ
|
|
150
|
-
|
|
151
|
-
function PSProductionComponent_Conditional_2_Conditional_64_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
152
|
-
i0.ɵɵelementStart(0, "div", 29);
|
|
153
|
-
i0.ɵɵtext(1, "No per-record predictions recorded for this run.");
|
|
154
|
-
i0.ɵɵelementEnd();
|
|
155
|
-
} }
|
|
156
|
-
function PSProductionComponent_Conditional_2_Conditional_64_Conditional_5_For_13_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
157
|
-
i0.ɵɵelementStart(0, "span", 52);
|
|
158
|
-
i0.ɵɵtext(1);
|
|
316
|
+
function PSProductionComponent_Conditional_2_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
317
|
+
i0.ɵɵelementStart(0, "div", 23);
|
|
318
|
+
i0.ɵɵconditionalCreate(1, PSProductionComponent_Conditional_2_Conditional_22_Conditional_1_Template, 10, 0, "div", 68)(2, PSProductionComponent_Conditional_2_Conditional_22_Conditional_2_Template, 3, 2);
|
|
159
319
|
i0.ɵɵelementEnd();
|
|
160
320
|
} if (rf & 2) {
|
|
161
|
-
const
|
|
321
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
162
322
|
i0.ɵɵadvance();
|
|
163
|
-
i0.ɵɵ
|
|
323
|
+
i0.ɵɵconditional(ctx_r1.selected.deployState === "idle" ? 1 : 2);
|
|
164
324
|
} }
|
|
165
|
-
function
|
|
166
|
-
i0.ɵɵ
|
|
167
|
-
i0.ɵɵ
|
|
168
|
-
i0.ɵɵ
|
|
169
|
-
i0.ɵɵ
|
|
170
|
-
i0.ɵɵ
|
|
171
|
-
i0.ɵɵ
|
|
172
|
-
i0.ɵɵ
|
|
173
|
-
i0.ɵɵtext(7);
|
|
174
|
-
i0.ɵɵconditionalCreate(8, PSProductionComponent_Conditional_2_Conditional_64_Conditional_5_For_13_Conditional_8_Template, 2, 1, "span", 52);
|
|
175
|
-
i0.ɵɵelementEnd();
|
|
176
|
-
i0.ɵɵelementStart(9, "td", 29);
|
|
177
|
-
i0.ɵɵtext(10);
|
|
178
|
-
i0.ɵɵpipe(11, "date");
|
|
179
|
-
i0.ɵɵelementEnd()();
|
|
325
|
+
function PSProductionComponent_Conditional_2_Conditional_31_Template(rf, ctx) { if (rf & 1) {
|
|
326
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
327
|
+
i0.ɵɵelementStart(0, "div", 16)(1, "button", 77);
|
|
328
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_31_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleRunFocus()); });
|
|
329
|
+
i0.ɵɵelement(2, "i", 22);
|
|
330
|
+
i0.ɵɵelementStart(3, "span");
|
|
331
|
+
i0.ɵɵtext(4);
|
|
332
|
+
i0.ɵɵelementEnd()()();
|
|
180
333
|
} if (rf & 2) {
|
|
181
|
-
const
|
|
182
|
-
const ctx_r3 = i0.ɵɵnextContext(4);
|
|
183
|
-
i0.ɵɵadvance(2);
|
|
184
|
-
i0.ɵɵtextInterpolate(d_r7.recordId);
|
|
185
|
-
i0.ɵɵadvance(2);
|
|
186
|
-
i0.ɵɵclassMap(ctx_r3.runBadge(d_r7.status));
|
|
334
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
187
335
|
i0.ɵɵadvance();
|
|
188
|
-
i0.ɵɵ
|
|
189
|
-
i0.ɵɵ
|
|
190
|
-
i0.ɵɵtextInterpolate(d_r7.score);
|
|
336
|
+
i0.ɵɵclassProp("active", ctx_r1.isRunFocused);
|
|
337
|
+
i0.ɵɵproperty("title", ctx_r1.isRunFocused ? "Exit focus (expand header & deployment)" : "Focus mode (collapse header & deployment)");
|
|
191
338
|
i0.ɵɵadvance();
|
|
192
|
-
i0.ɵɵ
|
|
339
|
+
i0.ɵɵclassProp("fa-compress", ctx_r1.isRunFocused)("fa-expand", !ctx_r1.isRunFocused);
|
|
193
340
|
i0.ɵɵadvance(2);
|
|
194
|
-
i0.ɵɵtextInterpolate(
|
|
341
|
+
i0.ɵɵtextInterpolate(ctx_r1.isRunFocused ? "Exit Focus" : "Focus");
|
|
195
342
|
} }
|
|
196
|
-
function
|
|
197
|
-
|
|
198
|
-
i0.ɵɵ
|
|
343
|
+
function PSProductionComponent_Conditional_2_Conditional_33_Template(rf, ctx) { if (rf & 1) {
|
|
344
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
345
|
+
i0.ɵɵelementStart(0, "div", 78)(1, "button", 79);
|
|
346
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_33_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.closeRun()); });
|
|
347
|
+
i0.ɵɵelement(2, "i", 80);
|
|
348
|
+
i0.ɵɵtext(3, " All runs ");
|
|
199
349
|
i0.ɵɵelementEnd();
|
|
200
|
-
i0.ɵɵelementStart(
|
|
201
|
-
i0.ɵɵtext(
|
|
202
|
-
i0.ɵɵelementEnd();
|
|
203
|
-
i0.ɵɵelementStart(7, "th");
|
|
204
|
-
i0.ɵɵtext(8, "Prediction");
|
|
205
|
-
i0.ɵɵelementEnd();
|
|
206
|
-
i0.ɵɵelementStart(9, "th");
|
|
207
|
-
i0.ɵɵtext(10, "Scored");
|
|
208
|
-
i0.ɵɵelementEnd()()();
|
|
209
|
-
i0.ɵɵelementStart(11, "tbody");
|
|
210
|
-
i0.ɵɵrepeaterCreate(12, PSProductionComponent_Conditional_2_Conditional_64_Conditional_5_For_13_Template, 12, 10, "tr", null, _forTrack2);
|
|
350
|
+
i0.ɵɵelementStart(4, "span", 64);
|
|
351
|
+
i0.ɵɵtext(5);
|
|
211
352
|
i0.ɵɵelementEnd()();
|
|
353
|
+
i0.ɵɵelement(6, "ps-predictions-grid", 81);
|
|
212
354
|
} if (rf & 2) {
|
|
213
|
-
const
|
|
214
|
-
i0.ɵɵadvance(
|
|
215
|
-
i0.ɵɵ
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const _r6 = i0.ɵɵgetCurrentView();
|
|
219
|
-
i0.ɵɵelementStart(0, "button", 46);
|
|
220
|
-
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_64_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.closeRun()); });
|
|
221
|
-
i0.ɵɵelement(1, "i", 47);
|
|
222
|
-
i0.ɵɵtext(2, " All runs ");
|
|
223
|
-
i0.ɵɵelementEnd();
|
|
224
|
-
i0.ɵɵconditionalCreate(3, PSProductionComponent_Conditional_2_Conditional_64_Conditional_3_Template, 1, 0, "mj-loading", 48)(4, PSProductionComponent_Conditional_2_Conditional_64_Conditional_4_Template, 2, 0, "div", 29)(5, PSProductionComponent_Conditional_2_Conditional_64_Conditional_5_Template, 14, 0, "table", 49);
|
|
225
|
-
} if (rf & 2) {
|
|
226
|
-
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
227
|
-
i0.ɵɵadvance(3);
|
|
228
|
-
i0.ɵɵconditional(ctx_r3.loadingDetails ? 3 : ctx_r3.runDetails.length === 0 ? 4 : 5);
|
|
355
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
356
|
+
i0.ɵɵadvance(5);
|
|
357
|
+
i0.ɵɵtextInterpolate1("Run: ", ctx_r1.selectedRunId);
|
|
358
|
+
i0.ɵɵadvance();
|
|
359
|
+
i0.ɵɵproperty("modelId", ctx_r1.selected.modelId)("runId", ctx_r1.selectedRunId)("entityName", ctx_r1.selectedTargetEntityName)("problemType", ctx_r1.selected.problemType)("title", ctx_r1.selected.label + " \u2014 Run Predictions")("height", ctx_r1.runGridHeight);
|
|
229
360
|
} }
|
|
230
|
-
function
|
|
361
|
+
function PSProductionComponent_Conditional_2_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
231
362
|
i0.ɵɵelement(0, "mj-loading", 28);
|
|
232
363
|
} }
|
|
233
|
-
function
|
|
364
|
+
function PSProductionComponent_Conditional_2_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
234
365
|
i0.ɵɵelementStart(0, "div", 29);
|
|
235
366
|
i0.ɵɵtext(1, "No runs recorded yet. Each time this model runs as a Record Process, its predictions are saved to the process run history \u2014 even without a scoring binding.");
|
|
236
367
|
i0.ɵɵelementEnd();
|
|
237
368
|
} }
|
|
238
|
-
function
|
|
239
|
-
i0.ɵɵelementStart(0, "span",
|
|
369
|
+
function PSProductionComponent_Conditional_2_Conditional_36_For_14_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
370
|
+
i0.ɵɵelementStart(0, "span", 87);
|
|
240
371
|
i0.ɵɵtext(1, "dry run");
|
|
241
372
|
i0.ɵɵelementEnd();
|
|
242
373
|
} }
|
|
243
|
-
function
|
|
244
|
-
const
|
|
245
|
-
i0.ɵɵelementStart(0, "tr",
|
|
246
|
-
i0.ɵɵlistener("click", function
|
|
374
|
+
function PSProductionComponent_Conditional_2_Conditional_36_For_14_Template(rf, ctx) { if (rf & 1) {
|
|
375
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
376
|
+
i0.ɵɵelementStart(0, "tr", 83);
|
|
377
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Conditional_36_For_14_Template_tr_click_0_listener() { const r_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openRun(r_r13.ID)); });
|
|
247
378
|
i0.ɵɵelementStart(1, "td");
|
|
248
379
|
i0.ɵɵtext(2);
|
|
249
380
|
i0.ɵɵpipe(3, "date");
|
|
250
381
|
i0.ɵɵelementEnd();
|
|
251
|
-
i0.ɵɵelementStart(4, "td")(5, "span",
|
|
382
|
+
i0.ɵɵelementStart(4, "td")(5, "span", 51);
|
|
252
383
|
i0.ɵɵtext(6);
|
|
253
384
|
i0.ɵɵelementEnd()();
|
|
254
|
-
i0.ɵɵelementStart(7, "td",
|
|
385
|
+
i0.ɵɵelementStart(7, "td", 84);
|
|
255
386
|
i0.ɵɵtext(8);
|
|
256
|
-
i0.ɵɵelementStart(9, "span",
|
|
387
|
+
i0.ɵɵelementStart(9, "span", 85);
|
|
257
388
|
i0.ɵɵtext(10);
|
|
258
389
|
i0.ɵɵelementEnd()();
|
|
259
390
|
i0.ɵɵelementStart(11, "td", 29);
|
|
260
391
|
i0.ɵɵtext(12);
|
|
261
392
|
i0.ɵɵelementEnd();
|
|
262
|
-
i0.ɵɵelementStart(13, "td",
|
|
263
|
-
i0.ɵɵconditionalCreate(14,
|
|
264
|
-
i0.ɵɵelement(15, "i",
|
|
393
|
+
i0.ɵɵelementStart(13, "td", 86);
|
|
394
|
+
i0.ɵɵconditionalCreate(14, PSProductionComponent_Conditional_2_Conditional_36_For_14_Conditional_14_Template, 2, 0, "span", 87);
|
|
395
|
+
i0.ɵɵelement(15, "i", 88);
|
|
265
396
|
i0.ɵɵelementEnd()();
|
|
266
397
|
} if (rf & 2) {
|
|
267
|
-
const
|
|
268
|
-
const
|
|
398
|
+
const r_r13 = ctx.$implicit;
|
|
399
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
269
400
|
i0.ɵɵadvance(2);
|
|
270
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 8,
|
|
401
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 8, r_r13.StartTime || r_r13.CreatedAt, "short"));
|
|
271
402
|
i0.ɵɵadvance(3);
|
|
272
|
-
i0.ɵɵclassMap(
|
|
403
|
+
i0.ɵɵclassMap(ctx_r1.runBadge(r_r13.Status));
|
|
273
404
|
i0.ɵɵadvance();
|
|
274
|
-
i0.ɵɵtextInterpolate(
|
|
405
|
+
i0.ɵɵtextInterpolate(r_r13.Status);
|
|
275
406
|
i0.ɵɵadvance(2);
|
|
276
|
-
i0.ɵɵtextInterpolate(
|
|
407
|
+
i0.ɵɵtextInterpolate(r_r13.SuccessCount);
|
|
277
408
|
i0.ɵɵadvance(2);
|
|
278
|
-
i0.ɵɵtextInterpolate1("/",
|
|
409
|
+
i0.ɵɵtextInterpolate1("/", r_r13.TotalItemCount ?? 0);
|
|
279
410
|
i0.ɵɵadvance(2);
|
|
280
|
-
i0.ɵɵtextInterpolate(
|
|
411
|
+
i0.ɵɵtextInterpolate(r_r13.ProcessName || "\u2014");
|
|
281
412
|
i0.ɵɵadvance(2);
|
|
282
|
-
i0.ɵɵconditional(
|
|
413
|
+
i0.ɵɵconditional(r_r13.DryRun ? 14 : -1);
|
|
283
414
|
} }
|
|
284
|
-
function
|
|
415
|
+
function PSProductionComponent_Conditional_2_Conditional_36_Template(rf, ctx) { if (rf & 1) {
|
|
285
416
|
i0.ɵɵelementStart(0, "table", 30)(1, "thead")(2, "tr")(3, "th");
|
|
286
417
|
i0.ɵɵtext(4, "When");
|
|
287
418
|
i0.ɵɵelementEnd();
|
|
@@ -297,124 +428,98 @@ function PSProductionComponent_Conditional_2_Conditional_67_Template(rf, ctx) {
|
|
|
297
428
|
i0.ɵɵelement(11, "th");
|
|
298
429
|
i0.ɵɵelementEnd()();
|
|
299
430
|
i0.ɵɵelementStart(12, "tbody");
|
|
300
|
-
i0.ɵɵrepeaterCreate(13,
|
|
431
|
+
i0.ɵɵrepeaterCreate(13, PSProductionComponent_Conditional_2_Conditional_36_For_14_Template, 16, 11, "tr", 82, _forTrack2);
|
|
301
432
|
i0.ɵɵelementEnd()();
|
|
302
433
|
} if (rf & 2) {
|
|
303
|
-
const
|
|
434
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
304
435
|
i0.ɵɵadvance(13);
|
|
305
|
-
i0.ɵɵrepeater(
|
|
436
|
+
i0.ɵɵrepeater(ctx_r1.runs);
|
|
306
437
|
} }
|
|
307
438
|
function PSProductionComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
308
439
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
309
|
-
i0.ɵɵ
|
|
310
|
-
i0.ɵɵ
|
|
440
|
+
i0.ɵɵconditionalCreate(0, PSProductionComponent_Conditional_2_Conditional_0_Template, 21, 4, "div", 4);
|
|
441
|
+
i0.ɵɵelementStart(1, "div", 5);
|
|
442
|
+
i0.ɵɵconditionalCreate(2, PSProductionComponent_Conditional_2_Conditional_2_Template, 5, 0, "div", 6);
|
|
443
|
+
i0.ɵɵelementStart(3, "as-split", 7);
|
|
444
|
+
i0.ɵɵlistener("dragEnd", function PSProductionComponent_Conditional_2_Template_as_split_dragEnd_3_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSplitDragEnd($event.sizes)); });
|
|
445
|
+
i0.ɵɵconditionalCreate(4, PSProductionComponent_Conditional_2_Conditional_4_Template, 13, 4, "as-split-area", 8);
|
|
446
|
+
i0.ɵɵelementStart(5, "as-split-area", 9)(6, "div", 10)(7, "div", 11);
|
|
447
|
+
i0.ɵɵconditionalCreate(8, PSProductionComponent_Conditional_2_Conditional_8_Template, 17, 12, "div", 12)(9, PSProductionComponent_Conditional_2_Conditional_9_Template, 17, 10, "div", 13);
|
|
311
448
|
i0.ɵɵelementEnd();
|
|
312
|
-
i0.ɵɵelementStart(
|
|
313
|
-
i0.ɵɵ
|
|
314
|
-
i0.ɵɵ
|
|
315
|
-
i0.ɵɵ
|
|
316
|
-
i0.ɵɵ
|
|
449
|
+
i0.ɵɵelementStart(10, "div", 14)(11, "div", 15);
|
|
450
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Template_div_click_11_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleDeploymentCollapse()); });
|
|
451
|
+
i0.ɵɵelementStart(12, "div", 16);
|
|
452
|
+
i0.ɵɵelement(13, "i", 17);
|
|
453
|
+
i0.ɵɵelementStart(14, "h3");
|
|
454
|
+
i0.ɵɵtext(15, "Deployment");
|
|
317
455
|
i0.ɵɵelementEnd();
|
|
318
|
-
i0.ɵɵelementStart(
|
|
319
|
-
i0.ɵɵtext(
|
|
320
|
-
i0.ɵɵelementEnd()();
|
|
321
|
-
i0.ɵɵelementStart(11, "div", 5)(12, "div", 6);
|
|
322
|
-
i0.ɵɵtext(13, "Bound (write-back)");
|
|
456
|
+
i0.ɵɵelementStart(16, "span", 18);
|
|
457
|
+
i0.ɵɵtext(17);
|
|
323
458
|
i0.ɵɵelementEnd();
|
|
324
|
-
i0.ɵɵ
|
|
325
|
-
i0.ɵɵtext(15);
|
|
326
|
-
i0.ɵɵelementEnd()();
|
|
327
|
-
i0.ɵɵelementStart(16, "div", 5)(17, "div", 6);
|
|
328
|
-
i0.ɵɵtext(18, "Idle");
|
|
459
|
+
i0.ɵɵconditionalCreate(18, PSProductionComponent_Conditional_2_Conditional_18_Template, 2, 2, "span", 19);
|
|
329
460
|
i0.ɵɵelementEnd();
|
|
330
|
-
i0.ɵɵelementStart(19, "div",
|
|
331
|
-
i0.ɵɵ
|
|
461
|
+
i0.ɵɵelementStart(19, "div", 20)(20, "button", 21);
|
|
462
|
+
i0.ɵɵlistener("click", function PSProductionComponent_Conditional_2_Template_button_click_20_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); $event.stopPropagation(); return i0.ɵɵresetView(ctx_r1.toggleDeploymentCollapse()); });
|
|
463
|
+
i0.ɵɵelement(21, "i", 22);
|
|
332
464
|
i0.ɵɵelementEnd()()();
|
|
333
|
-
i0.ɵɵ
|
|
334
|
-
i0.ɵɵtext(25, "Published models");
|
|
335
|
-
i0.ɵɵelementEnd();
|
|
336
|
-
i0.ɵɵelementStart(26, "span", 11);
|
|
337
|
-
i0.ɵɵtext(27);
|
|
338
|
-
i0.ɵɵelementEnd()();
|
|
339
|
-
i0.ɵɵelementStart(28, "div", 12);
|
|
340
|
-
i0.ɵɵrepeaterCreate(29, PSProductionComponent_Conditional_2_For_30_Template, 13, 13, "div", 13, _forTrack0);
|
|
341
|
-
i0.ɵɵelementEnd()();
|
|
342
|
-
i0.ɵɵelementStart(31, "div", 14)(32, "div", 15)(33, "div", 16)(34, "div", 17);
|
|
343
|
-
i0.ɵɵelement(35, "i");
|
|
344
|
-
i0.ɵɵelementEnd();
|
|
345
|
-
i0.ɵɵelementStart(36, "div", 18)(37, "h2", 19);
|
|
346
|
-
i0.ɵɵtext(38);
|
|
347
|
-
i0.ɵɵelementStart(39, "span", 20);
|
|
348
|
-
i0.ɵɵtext(40);
|
|
349
|
-
i0.ɵɵelementEnd()();
|
|
350
|
-
i0.ɵɵelementStart(41, "div", 21);
|
|
351
|
-
i0.ɵɵtext(42);
|
|
352
|
-
i0.ɵɵelementEnd()();
|
|
353
|
-
i0.ɵɵelementStart(43, "span", 22);
|
|
354
|
-
i0.ɵɵtext(44);
|
|
465
|
+
i0.ɵɵconditionalCreate(22, PSProductionComponent_Conditional_2_Conditional_22_Template, 3, 1, "div", 23);
|
|
355
466
|
i0.ɵɵelementEnd();
|
|
356
|
-
i0.ɵɵelementStart(
|
|
357
|
-
i0.ɵɵ
|
|
358
|
-
i0.ɵɵ
|
|
359
|
-
i0.ɵɵtext(
|
|
360
|
-
i0.ɵɵelementEnd()()();
|
|
361
|
-
i0.ɵɵelementStart(48, "div", 15)(49, "div", 10)(50, "h3");
|
|
362
|
-
i0.ɵɵtext(51, "Deployment");
|
|
467
|
+
i0.ɵɵelementStart(23, "div", 24)(24, "div", 25)(25, "div", 16);
|
|
468
|
+
i0.ɵɵelement(26, "i", 26);
|
|
469
|
+
i0.ɵɵelementStart(27, "h3");
|
|
470
|
+
i0.ɵɵtext(28, "Run history");
|
|
363
471
|
i0.ɵɵelementEnd();
|
|
364
|
-
i0.ɵɵelementStart(
|
|
365
|
-
i0.ɵɵtext(
|
|
366
|
-
i0.ɵɵelementEnd()();
|
|
367
|
-
i0.ɵɵelementStart(54, "div", 26);
|
|
368
|
-
i0.ɵɵconditionalCreate(55, PSProductionComponent_Conditional_2_Conditional_55_Template, 10, 0, "div", 27)(56, PSProductionComponent_Conditional_2_Conditional_56_Template, 3, 2);
|
|
472
|
+
i0.ɵɵelementStart(29, "span", 18);
|
|
473
|
+
i0.ɵɵtext(30, "last 90 days \u00B7 newest first");
|
|
369
474
|
i0.ɵɵelementEnd()();
|
|
370
|
-
i0.ɵɵ
|
|
371
|
-
i0.ɵɵtext(60, "Run history");
|
|
475
|
+
i0.ɵɵconditionalCreate(31, PSProductionComponent_Conditional_2_Conditional_31_Template, 5, 8, "div", 16);
|
|
372
476
|
i0.ɵɵelementEnd();
|
|
373
|
-
i0.ɵɵelementStart(
|
|
374
|
-
i0.ɵɵ
|
|
375
|
-
i0.ɵɵelementEnd()();
|
|
376
|
-
i0.ɵɵelementStart(
|
|
377
|
-
i0.ɵɵ
|
|
378
|
-
i0.ɵɵelementEnd()()()();
|
|
379
|
-
i0.ɵɵelementStart(68, "ps-operate-dialog", 31);
|
|
380
|
-
i0.ɵɵlistener("Close", function PSProductionComponent_Conditional_2_Template_ps_operate_dialog_Close_68_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onOperateClose($event)); });
|
|
477
|
+
i0.ɵɵelementStart(32, "div", 27);
|
|
478
|
+
i0.ɵɵconditionalCreate(33, PSProductionComponent_Conditional_2_Conditional_33_Template, 7, 7)(34, PSProductionComponent_Conditional_2_Conditional_34_Template, 1, 0, "mj-loading", 28)(35, PSProductionComponent_Conditional_2_Conditional_35_Template, 2, 0, "div", 29)(36, PSProductionComponent_Conditional_2_Conditional_36_Template, 15, 0, "table", 30);
|
|
479
|
+
i0.ɵɵelementEnd()()()()()();
|
|
480
|
+
i0.ɵɵelementStart(37, "ps-operate-dialog", 31);
|
|
481
|
+
i0.ɵɵlistener("Close", function PSProductionComponent_Conditional_2_Template_ps_operate_dialog_Close_37_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onOperateClose($event)); });
|
|
381
482
|
i0.ɵɵelementEnd();
|
|
382
483
|
} if (rf & 2) {
|
|
383
|
-
const
|
|
384
|
-
i0.ɵɵ
|
|
385
|
-
i0.ɵɵtextInterpolate(ctx_r3.models.length);
|
|
386
|
-
i0.ɵɵadvance(5);
|
|
387
|
-
i0.ɵɵtextInterpolate(ctx_r3.scheduledModelCount);
|
|
388
|
-
i0.ɵɵadvance(5);
|
|
389
|
-
i0.ɵɵtextInterpolate(ctx_r3.boundModelCount);
|
|
390
|
-
i0.ɵɵadvance(5);
|
|
391
|
-
i0.ɵɵtextInterpolate(ctx_r3.idleModelCount);
|
|
392
|
-
i0.ɵɵadvance(7);
|
|
393
|
-
i0.ɵɵtextInterpolate(ctx_r3.models.length);
|
|
394
|
-
i0.ɵɵadvance(2);
|
|
395
|
-
i0.ɵɵrepeater(ctx_r3.models);
|
|
396
|
-
i0.ɵɵadvance(5);
|
|
397
|
-
i0.ɵɵclassMap("st-" + ctx_r3.selected.deployState);
|
|
484
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
485
|
+
i0.ɵɵconditional(!ctx_r1.isRunFocused ? 0 : -1);
|
|
398
486
|
i0.ɵɵadvance();
|
|
399
|
-
i0.ɵɵ
|
|
400
|
-
i0.ɵɵadvance(
|
|
401
|
-
i0.ɵɵ
|
|
487
|
+
i0.ɵɵclassProp("list-collapsed", ctx_r1.isListCollapsed);
|
|
488
|
+
i0.ɵɵadvance();
|
|
489
|
+
i0.ɵɵconditional(ctx_r1.isListCollapsed ? 2 : -1);
|
|
490
|
+
i0.ɵɵadvance();
|
|
491
|
+
i0.ɵɵproperty("gutterSize", 6);
|
|
492
|
+
i0.ɵɵadvance();
|
|
493
|
+
i0.ɵɵconditional(!ctx_r1.isListCollapsed ? 4 : -1);
|
|
494
|
+
i0.ɵɵadvance();
|
|
495
|
+
i0.ɵɵproperty("size", ctx_r1.isListCollapsed ? 100 : ctx_r1.detailSizePct)("minSize", 50);
|
|
496
|
+
i0.ɵɵadvance();
|
|
497
|
+
i0.ɵɵclassProp("focused-run", ctx_r1.selectedRunId && ctx_r1.isRunFocused);
|
|
498
|
+
i0.ɵɵadvance();
|
|
499
|
+
i0.ɵɵclassProp("collapsed", ctx_r1.isHeaderCollapsed);
|
|
500
|
+
i0.ɵɵadvance();
|
|
501
|
+
i0.ɵɵconditional(!ctx_r1.isHeaderCollapsed ? 8 : 9);
|
|
402
502
|
i0.ɵɵadvance(2);
|
|
403
|
-
i0.ɵɵ
|
|
503
|
+
i0.ɵɵclassProp("collapsed", ctx_r1.isDeploymentCollapsed);
|
|
504
|
+
i0.ɵɵadvance(7);
|
|
505
|
+
i0.ɵɵtextInterpolate4("", ctx_r1.selected.processCount, " process", ctx_r1.selected.processCount === 1 ? "" : "es", " \u00B7 ", ctx_r1.selected.bindingCount, " binding", ctx_r1.selected.bindingCount === 1 ? "" : "s");
|
|
506
|
+
i0.ɵɵadvance();
|
|
507
|
+
i0.ɵɵconditional(ctx_r1.isDeploymentCollapsed && ctx_r1.selectedBindings.length > 0 ? 18 : -1);
|
|
404
508
|
i0.ɵɵadvance(2);
|
|
405
|
-
i0.ɵɵ
|
|
509
|
+
i0.ɵɵproperty("title", ctx_r1.isDeploymentCollapsed ? "Expand deployment" : "Collapse deployment");
|
|
510
|
+
i0.ɵɵattribute("aria-label", ctx_r1.isDeploymentCollapsed ? "Expand deployment" : "Collapse deployment");
|
|
511
|
+
i0.ɵɵadvance();
|
|
512
|
+
i0.ɵɵclassProp("fa-chevron-up", !ctx_r1.isDeploymentCollapsed)("fa-chevron-down", ctx_r1.isDeploymentCollapsed);
|
|
406
513
|
i0.ɵɵadvance();
|
|
407
|
-
i0.ɵɵ
|
|
514
|
+
i0.ɵɵconditional(!ctx_r1.isDeploymentCollapsed ? 22 : -1);
|
|
408
515
|
i0.ɵɵadvance();
|
|
409
|
-
i0.ɵɵ
|
|
410
|
-
i0.ɵɵadvance(
|
|
411
|
-
i0.ɵɵ
|
|
516
|
+
i0.ɵɵclassProp("drilldown-active", ctx_r1.selectedRunId)("focus-fill", ctx_r1.selectedRunId && ctx_r1.isRunFocused);
|
|
517
|
+
i0.ɵɵadvance(8);
|
|
518
|
+
i0.ɵɵconditional(ctx_r1.selectedRunId ? 31 : -1);
|
|
412
519
|
i0.ɵɵadvance(2);
|
|
413
|
-
i0.ɵɵconditional(
|
|
414
|
-
i0.ɵɵadvance(9);
|
|
415
|
-
i0.ɵɵconditional(ctx_r3.selectedRunId ? 64 : ctx_r3.loadingRuns ? 65 : ctx_r3.runs.length === 0 ? 66 : 67);
|
|
520
|
+
i0.ɵɵconditional(ctx_r1.selectedRunId ? 33 : ctx_r1.loadingRuns ? 34 : ctx_r1.runs.length === 0 ? 35 : 36);
|
|
416
521
|
i0.ɵɵadvance(4);
|
|
417
|
-
i0.ɵɵproperty("Visible",
|
|
522
|
+
i0.ɵɵproperty("Visible", ctx_r1.operateOpen)("modelId", ctx_r1.selected.modelId)("modelLabel", ctx_r1.selected.label)("engine", ctx_r1.engine)("provider", ctx_r1.ProviderToUse)("currentUser", ctx_r1.ProviderToUse.CurrentUser);
|
|
418
523
|
} }
|
|
419
524
|
/**
|
|
420
525
|
* Models in Production — the **model-centric** control tower. Every approved (Published) model appears
|
|
@@ -437,13 +542,26 @@ export class PSProductionComponent extends BaseAngularComponent {
|
|
|
437
542
|
selectedBindings = [];
|
|
438
543
|
runs = [];
|
|
439
544
|
loadingRuns = false;
|
|
545
|
+
loadingDetails = false;
|
|
440
546
|
/** Whether the "Operate this model" dialog is open for the selected model. */
|
|
441
547
|
operateOpen = false;
|
|
442
548
|
/** The run whose per-record predictions are drilled into (null = the run list). */
|
|
443
549
|
selectedRunId = null;
|
|
444
550
|
runDetails = [];
|
|
445
|
-
|
|
551
|
+
listSizePct = 30;
|
|
552
|
+
detailSizePct = 70;
|
|
553
|
+
isListCollapsed = false;
|
|
554
|
+
isHeaderCollapsed = false;
|
|
555
|
+
isDeploymentCollapsed = false;
|
|
556
|
+
isRunFocused = false;
|
|
557
|
+
get runGridHeight() {
|
|
558
|
+
if (this.isRunFocused || (this.isHeaderCollapsed && this.isDeploymentCollapsed)) {
|
|
559
|
+
return '740px';
|
|
560
|
+
}
|
|
561
|
+
return '520px';
|
|
562
|
+
}
|
|
446
563
|
ngOnInit() {
|
|
564
|
+
this.loadLayoutPrefs();
|
|
447
565
|
// Reactive: rebuild the published-model list on any MJ: ML Models change (save/delete/remote-invalidate).
|
|
448
566
|
this.modelsSub = this.engine
|
|
449
567
|
.ObserveProperty('_Models')
|
|
@@ -455,6 +573,83 @@ export class PSProductionComponent extends BaseAngularComponent {
|
|
|
455
573
|
ngOnDestroy() {
|
|
456
574
|
this.modelsSub?.unsubscribe();
|
|
457
575
|
}
|
|
576
|
+
// ---- layout splitter resizing & persistence ----
|
|
577
|
+
toggleHeaderCollapse() {
|
|
578
|
+
this.isHeaderCollapsed = !this.isHeaderCollapsed;
|
|
579
|
+
this.updateFocusState();
|
|
580
|
+
this.saveLayoutPrefs();
|
|
581
|
+
this.cdr.detectChanges();
|
|
582
|
+
}
|
|
583
|
+
toggleDeploymentCollapse() {
|
|
584
|
+
this.isDeploymentCollapsed = !this.isDeploymentCollapsed;
|
|
585
|
+
this.updateFocusState();
|
|
586
|
+
this.saveLayoutPrefs();
|
|
587
|
+
this.cdr.detectChanges();
|
|
588
|
+
}
|
|
589
|
+
toggleRunFocus() {
|
|
590
|
+
this.isRunFocused = !this.isRunFocused;
|
|
591
|
+
if (this.isRunFocused) {
|
|
592
|
+
this.isHeaderCollapsed = true;
|
|
593
|
+
this.isDeploymentCollapsed = true;
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
this.isHeaderCollapsed = false;
|
|
597
|
+
this.isDeploymentCollapsed = false;
|
|
598
|
+
}
|
|
599
|
+
this.saveLayoutPrefs();
|
|
600
|
+
this.cdr.detectChanges();
|
|
601
|
+
}
|
|
602
|
+
updateFocusState() {
|
|
603
|
+
this.isRunFocused = this.isHeaderCollapsed && this.isDeploymentCollapsed;
|
|
604
|
+
}
|
|
605
|
+
loadLayoutPrefs() {
|
|
606
|
+
const raw = UserInfoEngine.Instance.GetSetting('mj.predictiveStudio.production.layout');
|
|
607
|
+
if (raw) {
|
|
608
|
+
try {
|
|
609
|
+
const parsed = JSON.parse(raw);
|
|
610
|
+
if (typeof parsed.listSizePct === 'number' && parsed.listSizePct >= 15 && parsed.listSizePct <= 60) {
|
|
611
|
+
this.listSizePct = parsed.listSizePct;
|
|
612
|
+
this.detailSizePct = 100 - parsed.listSizePct;
|
|
613
|
+
}
|
|
614
|
+
if (typeof parsed.isListCollapsed === 'boolean') {
|
|
615
|
+
this.isListCollapsed = parsed.isListCollapsed;
|
|
616
|
+
}
|
|
617
|
+
if (typeof parsed.isHeaderCollapsed === 'boolean') {
|
|
618
|
+
this.isHeaderCollapsed = parsed.isHeaderCollapsed;
|
|
619
|
+
}
|
|
620
|
+
if (typeof parsed.isDeploymentCollapsed === 'boolean') {
|
|
621
|
+
this.isDeploymentCollapsed = parsed.isDeploymentCollapsed;
|
|
622
|
+
}
|
|
623
|
+
if (typeof parsed.isRunFocused === 'boolean') {
|
|
624
|
+
this.isRunFocused = parsed.isRunFocused;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
catch { }
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
onSplitDragEnd(sizes) {
|
|
631
|
+
if (Array.isArray(sizes) && sizes.length === 2 && typeof sizes[0] === 'number' && typeof sizes[1] === 'number') {
|
|
632
|
+
this.listSizePct = Math.round(sizes[0]);
|
|
633
|
+
this.detailSizePct = Math.round(sizes[1]);
|
|
634
|
+
this.saveLayoutPrefs();
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
toggleList() {
|
|
638
|
+
this.isListCollapsed = !this.isListCollapsed;
|
|
639
|
+
this.saveLayoutPrefs();
|
|
640
|
+
this.cdr.detectChanges();
|
|
641
|
+
}
|
|
642
|
+
saveLayoutPrefs() {
|
|
643
|
+
const prefs = {
|
|
644
|
+
listSizePct: this.listSizePct,
|
|
645
|
+
detailSizePct: this.detailSizePct,
|
|
646
|
+
isListCollapsed: this.isListCollapsed,
|
|
647
|
+
isHeaderCollapsed: this.isHeaderCollapsed,
|
|
648
|
+
isDeploymentCollapsed: this.isDeploymentCollapsed,
|
|
649
|
+
isRunFocused: this.isRunFocused,
|
|
650
|
+
};
|
|
651
|
+
UserInfoEngine.Instance.SetSettingDebounced('mj.predictiveStudio.production.layout', JSON.stringify(prefs));
|
|
652
|
+
}
|
|
458
653
|
// ---- KPIs ----
|
|
459
654
|
get scheduledModelCount() {
|
|
460
655
|
return this.models.filter((m) => m.deployState === 'scheduled' || m.scheduledCount > 0).length;
|
|
@@ -490,14 +685,15 @@ export class PSProductionComponent extends BaseAngularComponent {
|
|
|
490
685
|
+ bindings.filter((b) => b.Mode === 'Scheduled').length;
|
|
491
686
|
const lastScoredAt = bindings.reduce((acc, b) => (b.LastScoredAt && (!acc || b.LastScoredAt.getTime() > acc.getTime()) ? b.LastScoredAt : acc), null);
|
|
492
687
|
const lastRowCount = bindings.find((b) => b.LastRowCount != null)?.LastRowCount ?? null;
|
|
493
|
-
const
|
|
688
|
+
const score = primaryModelScore(m);
|
|
689
|
+
const holdoutMetric = score != null ? formatMetricValue(score.key, score.value) : '—';
|
|
494
690
|
return {
|
|
495
691
|
modelId: m.ID,
|
|
496
692
|
label: this.engine.ModelDisplayName(m),
|
|
497
693
|
algorithm: this.engine.AlgorithmName(m.AlgorithmID),
|
|
498
694
|
problemType: m.ProblemType ?? '—',
|
|
499
695
|
version: m.Version,
|
|
500
|
-
holdoutMetric
|
|
696
|
+
holdoutMetric,
|
|
501
697
|
deployState: bindings.length > 0 ? 'bound' : scheduledCount > 0 ? 'scheduled' : 'idle',
|
|
502
698
|
bindingCount: bindings.length,
|
|
503
699
|
processCount: processes.length,
|
|
@@ -531,6 +727,21 @@ export class PSProductionComponent extends BaseAngularComponent {
|
|
|
531
727
|
}
|
|
532
728
|
return '—';
|
|
533
729
|
}
|
|
730
|
+
get selectedTargetEntityName() {
|
|
731
|
+
if (this.selectedBindings.length > 0 && this.selectedBindings[0].targetEntity !== '—') {
|
|
732
|
+
return this.selectedBindings[0].targetEntity;
|
|
733
|
+
}
|
|
734
|
+
const model = this.engine?.PublishedModels?.find((m) => UUIDsEqual(m.ID, this.selected.modelId));
|
|
735
|
+
if (model?.PipelineID) {
|
|
736
|
+
const pipeline = this.engine?.Pipelines?.find((p) => UUIDsEqual(p.ID, model.PipelineID));
|
|
737
|
+
if (pipeline?.TargetEntityID) {
|
|
738
|
+
const ent = this.ProviderToUse.Entities.find((e) => UUIDsEqual(e.ID, pipeline.TargetEntityID));
|
|
739
|
+
if (ent)
|
|
740
|
+
return ent.Name;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return null;
|
|
744
|
+
}
|
|
534
745
|
// ---- selection + on-demand run history ----
|
|
535
746
|
get selected() {
|
|
536
747
|
return (this.models.find((m) => UUIDsEqual(m.modelId, this.selectedModelId)) ??
|
|
@@ -657,18 +868,18 @@ export class PSProductionComponent extends BaseAngularComponent {
|
|
|
657
868
|
return 'gray';
|
|
658
869
|
}
|
|
659
870
|
static ɵfac = /*@__PURE__*/ (() => { let ɵPSProductionComponent_BaseFactory; return function PSProductionComponent_Factory(__ngFactoryType__) { return (ɵPSProductionComponent_BaseFactory || (ɵPSProductionComponent_BaseFactory = i0.ɵɵgetInheritedFactory(PSProductionComponent)))(__ngFactoryType__ || PSProductionComponent); }; })();
|
|
660
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PSProductionComponent, selectors: [["ps-production"]], inputs: { engine: "engine" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 1, consts: [["data-testid", "ps-production-panel", 1, "ps-panel", "ps-production"], ["data-testid", "ps-production-empty", 1, "ps-empty"], [1, "ps-empty-ico"], [1, "fa-solid", "fa-satellite-dish"], ["data-testid", "ps-production-kpis", 1, "prod-kpis"], [1, "
|
|
871
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PSProductionComponent, selectors: [["ps-production"]], inputs: { engine: "engine" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 1, consts: [["data-testid", "ps-production-panel", 1, "ps-panel", "ps-production"], ["data-testid", "ps-production-empty", 1, "ps-empty"], [1, "ps-empty-ico"], [1, "fa-solid", "fa-satellite-dish"], ["data-testid", "ps-production-kpis", 1, "prod-kpis"], [1, "prod-layout"], ["data-testid", "ps-production-collapsed-rail", 1, "prod-collapsed-strip"], ["direction", "horizontal", "unit", "percent", 1, "prod-splitter", 3, "dragEnd", "gutterSize"], [3, "size", "minSize", "maxSize"], [3, "size", "minSize"], ["data-testid", "ps-production-detail", 1, "ps-col", "detail"], [1, "ps-card", "prod-header-card"], [1, "ps-card-body", "dh"], [1, "ps-card-body", "dh-compact"], [1, "ps-card", "prod-deployment-card"], [1, "ps-card-head", "clickable", 3, "click"], [2, "display", "flex", "align-items", "center", "gap", "8px"], [1, "fa-solid", "fa-network-wired", 2, "color", "var(--mj-brand-primary)"], [1, "ps-muted", "ps-small"], [1, "ps-badge", "gray", "ps-small"], [2, "display", "flex", "align-items", "center", "gap", "6px"], ["type", "button", 1, "ps-card-collapse-btn", 3, "click", "title"], [1, "fa-solid"], [1, "ps-card-body"], [1, "ps-card", "run-card"], [1, "ps-card-head"], [1, "fa-solid", "fa-clock-rotate-left", 2, "color", "var(--mj-status-info)"], [1, "ps-card-body", "run-card-body"], ["text", "Loading runs...", "size", "small"], [1, "ps-small", "ps-muted"], [1, "runs-table"], [3, "Close", "Visible", "modelId", "modelLabel", "engine", "provider", "currentUser"], [1, "ps-kpi"], [1, "label"], [1, "val"], ["type", "button", "aria-label", "Expand models list", "title", "Expand list", 1, "prod-rail-collapse", 3, "click"], [1, "fa-solid", "fa-chevron-right"], [1, "prod-collapsed-strip-label"], ["data-testid", "ps-production-list", 1, "ps-card", "mlist"], [2, "display", "flex", "gap", "6px", "align-items", "center"], [1, "ps-badge", "gray"], ["type", "button", "title", "Collapse list", "aria-label", "Collapse list", 1, "prod-collapse-btn", 3, "click"], [1, "fa-solid", "fa-chevron-left"], [1, "ps-card-body", 2, "padding", "8px"], ["data-testid", "ps-production-row", 1, "mrow", 3, "sel"], ["data-testid", "ps-production-row", 1, "mrow", 3, "click"], [1, "ico"], [2, "flex", "1", "min-width", "0"], [1, "nm"], [1, "ln2", "ps-muted", "ps-small"], [1, "meta"], [1, "ps-badge"], [1, "ps-mono", "ps-small", "ps-muted"], [1, "big-ico"], ["data-testid", "ps-production-detail-name"], [1, "ps-tag", "ps-mono"], [1, "ps-muted", "ps-small", "sub"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-production-operate", 3, "click"], [1, "fa-solid", "fa-rocket"], ["type", "button", "title", "Collapse model header", "aria-label", "Collapse model header", 1, "ps-card-collapse-btn", 3, "click"], [1, "fa-solid", "fa-chevron-up"], [1, "ps-card-body", "dh-compact", 3, "click"], [1, "mini-ico"], [1, "compact-info"], [1, "ps-tag", "ps-mono", "ps-small"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-production-operate-compact", 3, "click"], ["type", "button", "title", "Expand model header", "aria-label", "Expand model header", 1, "ps-card-collapse-btn", 3, "click"], [1, "fa-solid", "fa-chevron-down"], [1, "ps-callout", "info"], [1, "fa-solid", "fa-circle-info"], [1, "ps-small"], [1, "ps-section-title"], [1, "bind-row"], [1, "fa-solid", "fa-arrow-right-to-bracket", "ps-muted"], [2, "flex", "1"], [1, "ps-divider"], [1, "ps-row", 2, "justify-content", "space-between"], ["type", "button", 1, "ps-focus-toggle-btn", 3, "click", "title"], [1, "run-drill-nav"], ["data-testid", "ps-production-run-back", 1, "run-back", 3, "click"], [1, "fa-solid", "fa-arrow-left"], ["data-testid", "ps-production-run-grid", 3, "modelId", "runId", "entityName", "problemType", "title", "height"], ["data-testid", "ps-production-run", 1, "run-row"], ["data-testid", "ps-production-run", 1, "run-row", 3, "click"], [1, "ps-mono"], [1, "ps-muted"], [1, "run-right"], [1, "ps-tag", "amber"], [1, "fa-solid", "fa-chevron-right", "ps-muted"]], template: function PSProductionComponent_Template(rf, ctx) { if (rf & 1) {
|
|
661
872
|
i0.ɵɵelementStart(0, "div", 0);
|
|
662
|
-
i0.ɵɵconditionalCreate(1, PSProductionComponent_Conditional_1_Template, 7, 0, "div", 1)(2, PSProductionComponent_Conditional_2_Template,
|
|
873
|
+
i0.ɵɵconditionalCreate(1, PSProductionComponent_Conditional_1_Template, 7, 0, "div", 1)(2, PSProductionComponent_Conditional_2_Template, 38, 39);
|
|
663
874
|
i0.ɵɵelementEnd();
|
|
664
875
|
} if (rf & 2) {
|
|
665
876
|
i0.ɵɵadvance();
|
|
666
877
|
i0.ɵɵconditional(ctx.models.length === 0 ? 1 : 2);
|
|
667
|
-
} }, dependencies: [CommonModule, SharedGenericModule, i1.LoadingComponent, MJButtonDirective, PSOperateDialogComponent, i2.DatePipe], styles: ["/* ============================================================================\n Predictive Studio \u2014 shared panel styles (design-token compliant)\n Maps the mockup design system onto MemberJunction semantic --mj-* tokens.\n Loaded by every PS panel component (styleUrls) under ViewEncapsulation.None,\n so the class names are global within the PS dashboard subtree.\n No hardcoded colors except the intentional categorical node/algorithm palette\n (declared once as --ps-* custom props below) which must stay distinct across\n light/dark to remain readable as diagram accents.\n ============================================================================ */\n\n/* Categorical accents for DAG node types + algorithm chips. These are\n data-visualization colors that must remain distinct regardless of theme\n (allowed exception #3 in the design-token rules). */\n.ps-panel {\n --ps-node-source: #6b7280;\n --ps-node-feature: #2050c8;\n --ps-node-embedding: #7b3ff0;\n --ps-node-target: #1f9d57;\n --ps-node-algorithm: #d98213;\n /* budget-gauge categorical accents (reuse the node palette so light/dark stay distinct) */\n --ps-gauge-cost: var(--ps-node-algorithm);\n --ps-gauge-iterations: var(--ps-node-feature);\n}\n\n.ps-panel {\n display: block;\n height: 100%;\n}\n\n/* ---- generic layout helpers ---- */\n.ps-row { display: flex; gap: 16px; }\n.ps-col { display: flex; flex-direction: column; gap: 16px; }\n.ps-wrap { flex-wrap: wrap; }\n.ps-spacer { flex: 1; }\n.ps-muted { color: var(--mj-text-muted); }\n.ps-small { font-size: 12.5px; }\n.ps-mono { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 12.5px; }\n.ps-section-title {\n font-size: 12px; text-transform: uppercase; letter-spacing: .06em;\n color: var(--mj-text-muted); margin: 4px 0 2px; font-weight: 700;\n}\n\n/* ---- cards ---- */\n.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-card-head {\n display: flex; align-items: center; gap: 10px;\n padding: 14px 16px; border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-card-head h3 { font-size: 14.5px; margin: 0; font-weight: 650; color: var(--mj-text-primary); }\n.ps-card-body { padding: 16px; }\n\n/* ---- KPI tiles ---- */\n.ps-kpi {\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 8px; padding: 16px 18px;\n}\n.ps-kpi .label { font-size: 12px; color: var(--mj-text-muted); font-weight: 600; }\n.ps-kpi .val { font-size: 26px; font-weight: 720; letter-spacing: -.02em; margin-top: 2px; color: var(--mj-text-primary); }\n\n/* ---- badges ---- */\n.ps-badge {\n display: inline-flex; align-items: center; gap: 5px;\n padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 650; line-height: 1.7;\n}\n.ps-badge.gray { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.ps-badge.blue { background: var(--mj-status-info-bg); color: var(--mj-status-info-text); }\n.ps-badge.green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n.ps-badge.amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-badge.red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }\n\n/* recommendation-level chips (the ranking matrix payoff) */\n.ps-lvl {\n display: inline-flex; align-items: center; justify-content: center;\n min-width: 92px; padding: 4px 10px; border-radius: 7px;\n font-weight: 650; font-size: 11.5px; color: var(--mj-text-inverse);\n}\n.ps-lvl-Primary { background: var(--mj-status-success); }\n.ps-lvl-Strong { background: var(--mj-status-info); }\n.ps-lvl-Viable { background: var(--mj-status-warning); }\n.ps-lvl-Weak { background: var(--mj-text-disabled); }\n.ps-lvl-NotRecommended { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n/* ---- tags ---- */\n.ps-tag {\n display: inline-block; padding: 2px 8px; border-radius: 6px;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary);\n font-size: 11.5px; font-weight: 600;\n}\n.ps-tag.muted { opacity: .6; }\n.ps-divider { height: 1px; background: var(--mj-border-subtle); margin: 8px 0; }\n\n/* ---- tables ---- */\n.ps-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.ps-table th {\n text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 9px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.ps-table td { padding: 11px 12px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-primary); }\n.ps-table tr:hover td { background: var(--mj-bg-surface-hover); }\n.ps-table .num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.ps-rank {\n width: 22px; height: 22px; border-radius: 6px; background: var(--mj-bg-surface-sunken);\n display: inline-grid; place-items: center; font-weight: 700; font-size: 11.5px; color: var(--mj-text-secondary);\n}\n.ps-rank.gold { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n\n/* ---- progress bars ---- */\n.ps-bar { height: 8px; border-radius: 999px; background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-bar > span { display: block; height: 100%; border-radius: 999px; background: var(--mj-brand-primary); }\n.ps-bar.warn > span { background: var(--mj-status-warning); }\n.ps-bar.run > span { background: var(--mj-brand-primary); }\n\n.ps-fbar { display: grid; grid-template-columns: minmax(150px, 1.3fr) 2fr 56px; align-items: center; gap: 14px; padding: 8px 0; }\n.ps-fbar + .ps-fbar { border-top: 1px solid var(--mj-border-subtle); }\n.ps-fbar .track { height: 10px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-fbar .track > span { display: block; height: 100%; border-radius: var(--mj-radius-full); background: var(--mj-brand-primary); }\n.ps-fbar .track > span.warn { background: var(--mj-status-warning); }\n.ps-fbar .name { color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.ps-fbar > .ps-mono { text-align: right; color: var(--mj-text-secondary); font-variant-numeric: tabular-nums; }\n\n/* gauge */\n.ps-gauge {\n position: relative; width: 64px; height: 64px; border-radius: 50%; flex: 0 0 auto;\n background: conic-gradient(var(--ps-gauge-color, var(--mj-brand-primary)) calc(var(--ps-p, 40) * 1%), var(--mj-bg-surface-sunken) 0);\n display: grid; place-items: center;\n}\n.ps-gauge::after { content: ''; position: absolute; inset: 9px; background: var(--mj-bg-surface); border-radius: 50%; }\n.ps-gauge .g-val { position: relative; font-weight: 720; font-size: 14px; color: var(--mj-text-primary); }\n\n/* warning / info callouts */\n.ps-callout { display: flex; gap: 11px; padding: 12px 14px; border-radius: 10px; border: 1px solid; }\n.ps-callout.warn { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); color: var(--mj-status-warning-text); }\n.ps-callout.info { background: var(--mj-status-info-bg); border-color: var(--mj-status-info-border); color: var(--mj-status-info-text); }\n.ps-callout.success { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); color: var(--mj-status-success-text); }\n.ps-callout i { font-size: 16px; margin-top: 1px; }\n\n/* lifecycle stepper */\n.ps-stepper { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }\n.ps-step { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--mj-text-muted); }\n.ps-step .pip {\n width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--mj-border-strong);\n display: grid; place-items: center; font-size: 11px;\n}\n.ps-step.done { color: var(--mj-status-success-text); }\n.ps-step.done .pip { background: var(--mj-status-success); border-color: var(--mj-status-success); color: var(--mj-text-inverse); }\n.ps-step.curr { color: var(--mj-brand-primary); }\n.ps-step.curr .pip { border-color: var(--mj-brand-primary); color: var(--mj-brand-primary); }\n.ps-step .ln { width: 26px; height: 2px; background: var(--mj-border-strong); }\n\n/* ---- DAG flow canvas ---- */\n.ps-flow {\n position: relative;\n background:\n linear-gradient(var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n linear-gradient(90deg, var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default); border-radius: 10px;\n min-height: 620px; overflow: hidden;\n}\n.ps-node {\n position: absolute; width: 190px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong); border-left-width: 3px; border-radius: 8px;\n cursor: pointer;\n}\n.ps-node .nh {\n display: flex; align-items: center; gap: 8px; padding: 9px 11px;\n border-bottom: 1px solid var(--mj-border-subtle); font-weight: 650; font-size: 12.5px; color: var(--mj-text-primary);\n}\n.ps-node .nh i.tile {\n width: 24px; height: 24px; border-radius: 6px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 12px; flex: 0 0 auto;\n}\n.ps-node .nh .ps-tag { margin-left: auto; }\n.ps-node .nb { padding: 9px 11px; font-size: 12px; color: var(--mj-text-secondary); }\n.ps-node .nb-row { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; }\n.ps-node .nb-row .k { color: var(--mj-text-muted); }\n.ps-node.src { border-left-color: var(--ps-node-source); }\n.ps-node.src .nh i.tile { background: var(--ps-node-source); }\n.ps-node.feat { border-left-color: var(--ps-node-feature); }\n.ps-node.feat .nh i.tile { background: var(--ps-node-feature); }\n.ps-node.emb { border-left-color: var(--ps-node-embedding); }\n.ps-node.emb .nh i.tile { background: var(--ps-node-embedding); }\n.ps-node.target { border-left-color: var(--ps-node-target); }\n.ps-node.target .nh i.tile { background: var(--ps-node-target); }\n.ps-node.algo { border-left-color: var(--ps-node-algorithm); }\n.ps-node.algo .nh i.tile { background: var(--ps-node-algorithm); }\n.ps-node.output { border-left-color: var(--mj-status-success); }\n.ps-node.output .nh i.tile { background: var(--mj-status-success); }\n.ps-node.selected {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n.ps-node .port {\n position: absolute; width: 11px; height: 11px; border-radius: 50%;\n background: var(--mj-bg-surface); border: 2px solid var(--mj-brand-primary);\n top: 50%; transform: translateY(-50%);\n}\n.ps-node .port.in { left: -6px; }\n.ps-node .port.out { right: -6px; }\nsvg.ps-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }\nsvg.ps-edges path { stroke: color-mix(in srgb, var(--mj-brand-primary) 45%, transparent); stroke-width: 2; fill: none; }\n\n/* palette chips */\n.ps-pchip {\n display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border-radius: 8px;\n border: 1px dashed var(--mj-border-strong); background: var(--mj-bg-surface);\n font-size: 12.5px; font-weight: 600; color: var(--mj-text-secondary); cursor: grab;\n}\n.ps-pchip i { font-size: 12px; color: var(--mj-text-inverse); width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center; }\n.ps-pchip.s i { background: var(--ps-node-source); }\n.ps-pchip.f i { background: var(--ps-node-feature); }\n.ps-pchip.e i { background: var(--ps-node-embedding); }\n.ps-pchip.t i { background: var(--ps-node-target); }\n.ps-pchip.a i { background: var(--ps-node-algorithm); }\n\n/* segmented control */\n.ps-seg { display: inline-flex; border: 1px solid var(--mj-border-default); border-radius: 8px; overflow: hidden; }\n.ps-seg button {\n border: none; background: var(--mj-bg-surface); color: var(--mj-text-secondary);\n padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer;\n border-right: 1px solid var(--mj-border-default);\n}\n.ps-seg button:last-child { border-right: none; }\n.ps-seg button.on { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n\n/* field control */\n.ps-field { margin-bottom: 14px; }\n.ps-field > label {\n display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; margin-bottom: 6px;\n}\n.ps-input {\n width: 100%; padding: 8px 10px; border: 1px solid var(--mj-border-default);\n border-radius: 6px; font-size: 13px; background: var(--mj-bg-surface); color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n.ps-input:focus { outline: none; border-color: var(--mj-brand-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); }\n\n/* loading container */\n.ps-loading { display: flex; align-items: center; justify-content: center; padding: 60px 0; }\n\n/* ---- empty / prompt states ---- */\n.ps-empty {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n text-align: center; gap: 10px; padding: 56px 24px; color: var(--mj-text-muted);\n}\n.ps-empty .ps-empty-ico {\n width: 60px; height: 60px; border-radius: 16px; display: grid; place-items: center;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-disabled); font-size: 24px;\n}\n.ps-empty h3 { margin: 4px 0 0; font-size: 16px; font-weight: 650; color: var(--mj-text-secondary); }\n.ps-empty p { margin: 0; max-width: 420px; font-size: 13px; line-height: 1.5; }\n\n/* ---- confirm modal ---- */\n.ps-modal-backdrop {\n position: fixed; inset: 0; z-index: 1000;\n background: var(--mj-bg-overlay);\n display: flex; align-items: center; justify-content: center; padding: 24px;\n}\n.ps-modal {\n width: 100%; max-width: 480px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default); border-radius: 14px;\n box-shadow: var(--mj-shadow-lg, var(--mj-shadow-sm)); overflow: hidden;\n}\n.ps-modal-head {\n display: flex; align-items: center; gap: 12px; padding: 18px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-modal-head .ico {\n width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;\n font-size: 16px; flex: 0 0 auto;\n background: var(--mj-status-info-bg); color: var(--mj-status-info-text);\n}\n.ps-modal-head.warn .ico { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-modal-head.danger .ico { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-modal-head h3 { margin: 0; font-size: 15.5px; font-weight: 650; color: var(--mj-text-primary); }\n.ps-modal-body { padding: 18px 20px; font-size: 13.5px; line-height: 1.55; color: var(--mj-text-secondary); }\n.ps-modal-body .ps-field { margin-top: 14px; margin-bottom: 0; }\n.ps-modal-foot {\n display: flex; align-items: center; gap: 10px; padding: 14px 20px;\n border-top: 1px solid var(--mj-border-subtle); background: var(--mj-bg-surface-card);\n}\n.ps-modal-foot .ps-spacer { flex: 1; }\n", "/* Models in Production \u2014 model-centric control tower (master/detail). All colors via --mj-* tokens. */\n\n.ps-production {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 4px;\n}\n\n.prod-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 14px;\n}\n\n.prod-layout {\n display: grid;\n grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);\n gap: 16px;\n align-items: start;\n}\n@media (max-width: 900px) {\n .prod-layout { grid-template-columns: 1fr; }\n}\n\n/* master list */\n.prod-layout .mlist .mrow {\n display: flex;\n align-items: center;\n gap: 11px;\n padding: 10px 10px;\n border-radius: 9px;\n cursor: pointer;\n}\n.prod-layout .mlist .mrow:hover { background: var(--mj-bg-surface-hover); }\n.prod-layout .mlist .mrow.sel { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n.prod-layout .mlist .mrow .ico {\n width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 13px; flex: 0 0 auto;\n}\n.prod-layout .mlist .mrow .nm { font-weight: 640; font-size: 14px; color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.prod-layout .mlist .mrow .ln2 { margin-top: 2px; }\n.prod-layout .mlist .mrow .meta { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex: 0 0 auto; }\n\n/* deploy-state icon colors (master + detail) */\n.st-bound { background: var(--mj-status-success); }\n.st-scheduled { background: var(--mj-status-info); }\n.st-idle { background: var(--mj-text-disabled); }\n\n/* detail */\n.prod-layout .detail { display: flex; flex-direction: column; gap: 14px; }\n.prod-layout .detail .dh { display: flex; align-items: center; gap: 13px; }\n.prod-layout .detail .dh h2 { margin: 0; font-size: 17px; font-weight: 680; color: var(--mj-text-primary); }\n.prod-layout .detail .dh .sub { margin-top: 3px; }\n.prod-layout .detail .big-ico {\n width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 16px; flex: 0 0 auto;\n}\n\n/* binding rows */\n.bind-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--mj-border-subtle); }\n.bind-row:last-child { border-bottom: none; }\n\n/* run history table */\n.runs-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.runs-table th {\n text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default);\n}\n.runs-table td { padding: 7px 8px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-secondary); }\n.runs-table tr:last-child td { border-bottom: none; }\n.runs-table tr.run-row { cursor: pointer; }\n.runs-table tr.run-row:hover td { background: var(--mj-bg-surface-hover); }\n.runs-table .run-right { text-align: right; white-space: nowrap; }\n.runs-table .run-right i { margin-left: 8px; opacity: .5; }\n\n.run-back {\n display: inline-flex; align-items: center; gap: 6px; cursor: pointer;\n background: none; border: none; color: var(--mj-text-link); font-size: 13px; padding: 0 0 10px;\n}\n\n/* empty state CTA spacing (shared .ps-empty) */\n.ps-production .ps-empty p { max-width: 520px; }\n"], encapsulation: 2 });
|
|
878
|
+
} }, dependencies: [CommonModule, AngularSplitModule, i1.SplitComponent, i1.SplitAreaComponent, SharedGenericModule, i2.LoadingComponent, MJButtonDirective, PSOperateDialogComponent, PSPredictionsGridComponent, i3.DatePipe], styles: ["/* ============================================================================\n Predictive Studio \u2014 shared panel styles (design-token compliant)\n Maps the mockup design system onto MemberJunction semantic --mj-* tokens.\n Loaded by every PS panel component (styleUrls) under ViewEncapsulation.None,\n so the class names are global within the PS dashboard subtree.\n No hardcoded colors except the intentional categorical node/algorithm palette\n (declared once as --ps-* custom props below) which must stay distinct across\n light/dark to remain readable as diagram accents.\n ============================================================================ */\n\n/* Categorical accents for DAG node types + algorithm chips. These are\n data-visualization colors that must remain distinct regardless of theme\n (allowed exception #3 in the design-token rules). */\n.ps-panel {\n --ps-node-source: #6b7280;\n --ps-node-feature: #2050c8;\n --ps-node-embedding: #7b3ff0;\n --ps-node-target: #1f9d57;\n --ps-node-algorithm: #d98213;\n /* budget-gauge categorical accents (reuse the node palette so light/dark stay distinct) */\n --ps-gauge-cost: var(--ps-node-algorithm);\n --ps-gauge-iterations: var(--ps-node-feature);\n}\n\n.ps-panel {\n display: block;\n height: 100%;\n}\n\n/* ---- generic layout helpers ---- */\n.ps-row { display: flex; gap: 16px; }\n.ps-col { display: flex; flex-direction: column; gap: 16px; }\n.ps-wrap { flex-wrap: wrap; }\n.ps-spacer { flex: 1; }\n.ps-muted { color: var(--mj-text-muted); }\n.ps-small { font-size: 12.5px; }\n.ps-mono { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 12.5px; }\n.ps-section-title {\n font-size: 12px; text-transform: uppercase; letter-spacing: .06em;\n color: var(--mj-text-muted); margin: 4px 0 2px; font-weight: 700;\n}\n\n/* ---- cards ---- */\n.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-card-head {\n display: flex; align-items: center; gap: 10px;\n padding: 14px 16px; border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-card-head h3 { font-size: 14.5px; margin: 0; font-weight: 650; color: var(--mj-text-primary); }\n.ps-card-body { padding: 16px; }\n\n/* ---- KPI tiles ---- */\n.ps-kpi {\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 8px; padding: 16px 18px;\n}\n.ps-kpi .label { font-size: 12px; color: var(--mj-text-muted); font-weight: 600; }\n.ps-kpi .val { font-size: 26px; font-weight: 720; letter-spacing: -.02em; margin-top: 2px; color: var(--mj-text-primary); }\n\n/* ---- badges ---- */\n.ps-badge {\n display: inline-flex; align-items: center; gap: 5px;\n padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 650; line-height: 1.7;\n}\n.ps-badge.gray { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.ps-badge.blue { background: var(--mj-status-info-bg); color: var(--mj-status-info-text); }\n.ps-badge.green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n.ps-badge.amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-badge.red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }\n\n/* recommendation-level chips (the ranking matrix payoff) */\n.ps-lvl {\n display: inline-flex; align-items: center; justify-content: center;\n min-width: 92px; padding: 4px 10px; border-radius: 7px;\n font-weight: 650; font-size: 11.5px; color: var(--mj-text-inverse);\n}\n.ps-lvl-Primary { background: var(--mj-status-success); }\n.ps-lvl-Strong { background: var(--mj-status-info); }\n.ps-lvl-Viable { background: var(--mj-status-warning); }\n.ps-lvl-Weak { background: var(--mj-text-disabled); }\n.ps-lvl-NotRecommended { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n/* ---- tags ---- */\n.ps-tag {\n display: inline-block; padding: 2px 8px; border-radius: 6px;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary);\n font-size: 11.5px; font-weight: 600;\n}\n.ps-tag.muted { opacity: .6; }\n.ps-divider { height: 1px; background: var(--mj-border-subtle); margin: 8px 0; }\n\n/* ---- tables ---- */\n.ps-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.ps-table th {\n text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 9px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.ps-table td { padding: 11px 12px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-primary); }\n.ps-table tr:hover td { background: var(--mj-bg-surface-hover); }\n.ps-table .num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.ps-rank {\n width: 22px; height: 22px; border-radius: 6px; background: var(--mj-bg-surface-sunken);\n display: inline-grid; place-items: center; font-weight: 700; font-size: 11.5px; color: var(--mj-text-secondary);\n}\n.ps-rank.gold { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n\n/* ---- progress bars ---- */\n.ps-bar { height: 8px; border-radius: 999px; background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-bar > span { display: block; height: 100%; border-radius: 999px; background: var(--mj-brand-primary); }\n.ps-bar.warn > span { background: var(--mj-status-warning); }\n.ps-bar.run > span { background: var(--mj-brand-primary); }\n\n.ps-fbar { display: grid; grid-template-columns: minmax(150px, 1.3fr) 2fr 56px; align-items: center; gap: 14px; padding: 8px 0; }\n.ps-fbar + .ps-fbar { border-top: 1px solid var(--mj-border-subtle); }\n.ps-fbar .track { height: 10px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-fbar .track > span { display: block; height: 100%; border-radius: var(--mj-radius-full); background: var(--mj-brand-primary); }\n.ps-fbar .track > span.warn { background: var(--mj-status-warning); }\n.ps-fbar .name { color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.ps-fbar > .ps-mono { text-align: right; color: var(--mj-text-secondary); font-variant-numeric: tabular-nums; }\n\n/* gauge */\n.ps-gauge {\n position: relative; width: 64px; height: 64px; border-radius: 50%; flex: 0 0 auto;\n background: conic-gradient(var(--ps-gauge-color, var(--mj-brand-primary)) calc(var(--ps-p, 40) * 1%), var(--mj-bg-surface-sunken) 0);\n display: grid; place-items: center;\n}\n.ps-gauge::after { content: ''; position: absolute; inset: 9px; background: var(--mj-bg-surface); border-radius: 50%; }\n.ps-gauge .g-val { position: relative; font-weight: 720; font-size: 14px; color: var(--mj-text-primary); }\n\n/* warning / info callouts */\n.ps-callout { display: flex; gap: 11px; padding: 12px 14px; border-radius: 10px; border: 1px solid; }\n.ps-callout.warn { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); color: var(--mj-status-warning-text); }\n.ps-callout.info { background: var(--mj-status-info-bg); border-color: var(--mj-status-info-border); color: var(--mj-status-info-text); }\n.ps-callout.success { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); color: var(--mj-status-success-text); }\n.ps-callout i { font-size: 16px; margin-top: 1px; }\n\n/* lifecycle stepper */\n.ps-stepper { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }\n.ps-step { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--mj-text-muted); }\n.ps-step .pip {\n width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--mj-border-strong);\n display: grid; place-items: center; font-size: 11px;\n}\n.ps-step.done { color: var(--mj-status-success-text); }\n.ps-step.done .pip { background: var(--mj-status-success); border-color: var(--mj-status-success); color: var(--mj-text-inverse); }\n.ps-step.curr { color: var(--mj-brand-primary); }\n.ps-step.curr .pip { border-color: var(--mj-brand-primary); color: var(--mj-brand-primary); }\n.ps-step .ln { width: 26px; height: 2px; background: var(--mj-border-strong); }\n\n/* ---- DAG flow canvas ---- */\n.ps-flow {\n position: relative;\n background:\n linear-gradient(var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n linear-gradient(90deg, var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default); border-radius: 10px;\n min-height: 620px; overflow: hidden;\n}\n.ps-node {\n position: absolute; width: 190px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong); border-left-width: 3px; border-radius: 8px;\n cursor: pointer;\n}\n.ps-node .nh {\n display: flex; align-items: center; gap: 8px; padding: 9px 11px;\n border-bottom: 1px solid var(--mj-border-subtle); font-weight: 650; font-size: 12.5px; color: var(--mj-text-primary);\n}\n.ps-node .nh i.tile {\n width: 24px; height: 24px; border-radius: 6px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 12px; flex: 0 0 auto;\n}\n.ps-node .nh .ps-tag { margin-left: auto; }\n.ps-node .nb { padding: 9px 11px; font-size: 12px; color: var(--mj-text-secondary); }\n.ps-node .nb-row { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; }\n.ps-node .nb-row .k { color: var(--mj-text-muted); }\n.ps-node.src { border-left-color: var(--ps-node-source); }\n.ps-node.src .nh i.tile { background: var(--ps-node-source); }\n.ps-node.feat { border-left-color: var(--ps-node-feature); }\n.ps-node.feat .nh i.tile { background: var(--ps-node-feature); }\n.ps-node.emb { border-left-color: var(--ps-node-embedding); }\n.ps-node.emb .nh i.tile { background: var(--ps-node-embedding); }\n.ps-node.target { border-left-color: var(--ps-node-target); }\n.ps-node.target .nh i.tile { background: var(--ps-node-target); }\n.ps-node.algo { border-left-color: var(--ps-node-algorithm); }\n.ps-node.algo .nh i.tile { background: var(--ps-node-algorithm); }\n.ps-node.output { border-left-color: var(--mj-status-success); }\n.ps-node.output .nh i.tile { background: var(--mj-status-success); }\n.ps-node.selected {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n.ps-node .port {\n position: absolute; width: 11px; height: 11px; border-radius: 50%;\n background: var(--mj-bg-surface); border: 2px solid var(--mj-brand-primary);\n top: 50%; transform: translateY(-50%);\n}\n.ps-node .port.in { left: -6px; }\n.ps-node .port.out { right: -6px; }\nsvg.ps-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }\nsvg.ps-edges path { stroke: color-mix(in srgb, var(--mj-brand-primary) 45%, transparent); stroke-width: 2; fill: none; }\n\n/* palette chips */\n.ps-pchip {\n display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border-radius: 8px;\n border: 1px dashed var(--mj-border-strong); background: var(--mj-bg-surface);\n font-size: 12.5px; font-weight: 600; color: var(--mj-text-secondary); cursor: grab;\n}\n.ps-pchip i { font-size: 12px; color: var(--mj-text-inverse); width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center; }\n.ps-pchip.s i { background: var(--ps-node-source); }\n.ps-pchip.f i { background: var(--ps-node-feature); }\n.ps-pchip.e i { background: var(--ps-node-embedding); }\n.ps-pchip.t i { background: var(--ps-node-target); }\n.ps-pchip.a i { background: var(--ps-node-algorithm); }\n\n/* segmented control */\n.ps-seg { display: inline-flex; border: 1px solid var(--mj-border-default); border-radius: 8px; overflow: hidden; }\n.ps-seg button {\n border: none; background: var(--mj-bg-surface); color: var(--mj-text-secondary);\n padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer;\n border-right: 1px solid var(--mj-border-default);\n}\n.ps-seg button:last-child { border-right: none; }\n.ps-seg button.on { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n\n/* field control */\n.ps-field { margin-bottom: 14px; }\n.ps-field > label {\n display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; margin-bottom: 6px;\n}\n.ps-input {\n width: 100%; padding: 8px 10px; border: 1px solid var(--mj-border-default);\n border-radius: 6px; font-size: 13px; background: var(--mj-bg-surface); color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n.ps-input:focus { outline: none; border-color: var(--mj-brand-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); }\n\n/* loading container */\n.ps-loading { display: flex; align-items: center; justify-content: center; padding: 60px 0; }\n\n/* ---- empty / prompt states ---- */\n.ps-empty {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n text-align: center; gap: 10px; padding: 56px 24px; color: var(--mj-text-muted);\n}\n.ps-empty .ps-empty-ico {\n width: 60px; height: 60px; border-radius: 16px; display: grid; place-items: center;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-disabled); font-size: 24px;\n}\n.ps-empty h3 { margin: 4px 0 0; font-size: 16px; font-weight: 650; color: var(--mj-text-secondary); }\n.ps-empty p { margin: 0; max-width: 420px; font-size: 13px; line-height: 1.5; }\n\n/* ---- confirm modal ---- */\n.ps-modal-backdrop {\n position: fixed; inset: 0; z-index: 1000;\n background: var(--mj-bg-overlay);\n display: flex; align-items: center; justify-content: center; padding: 24px;\n}\n.ps-modal {\n width: 100%; max-width: 480px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default); border-radius: 14px;\n box-shadow: var(--mj-shadow-lg, var(--mj-shadow-sm)); overflow: hidden;\n}\n.ps-modal-head {\n display: flex; align-items: center; gap: 12px; padding: 18px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-modal-head .ico {\n width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;\n font-size: 16px; flex: 0 0 auto;\n background: var(--mj-status-info-bg); color: var(--mj-status-info-text);\n}\n.ps-modal-head.warn .ico { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-modal-head.danger .ico { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-modal-head h3 { margin: 0; font-size: 15.5px; font-weight: 650; color: var(--mj-text-primary); }\n.ps-modal-body { padding: 18px 20px; font-size: 13.5px; line-height: 1.55; color: var(--mj-text-secondary); }\n.ps-modal-body .ps-field { margin-top: 14px; margin-bottom: 0; }\n.ps-modal-foot {\n display: flex; align-items: center; gap: 10px; padding: 14px 20px;\n border-top: 1px solid var(--mj-border-subtle); background: var(--mj-bg-surface-card);\n}\n.ps-modal-foot .ps-spacer { flex: 1; }\n", "/* Models in Production \u2014 model-centric control tower (master/detail). All colors via --mj-* tokens. */\n\n.ps-production {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n width: 100%;\n overflow: hidden;\n gap: 16px;\n padding: 4px;\n}\n\n.prod-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 14px;\n flex: 0 0 auto;\n}\n\n.prod-layout {\n display: flex;\n flex-direction: row;\n flex: 1;\n min-height: 0;\n height: 100%;\n overflow: hidden;\n position: relative;\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n.prod-splitter {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-page);\n}\n\n.prod-collapsed-strip {\n width: 44px;\n flex: 0 0 44px;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n z-index: 10;\n}\n\n.prod-rail-collapse {\n background: transparent;\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n border-radius: var(--mj-radius-sm);\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.prod-rail-collapse:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.prod-collapsed-strip-label {\n color: var(--mj-text-muted);\n font-size: 16px;\n margin-top: 8px;\n}\n\n.prod-collapse-btn {\n background: transparent;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n border-radius: var(--mj-radius-sm);\n width: 26px;\n height: 26px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.prod-collapse-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n/* master list \u2014 own scroll column */\n.prod-layout .mlist {\n min-height: 0;\n overflow-y: auto;\n align-self: stretch;\n height: 100%;\n border-radius: 0;\n border: none;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.prod-layout .mlist .mrow {\n display: flex;\n align-items: center;\n gap: 11px;\n padding: 10px 10px;\n border-radius: 9px;\n cursor: pointer;\n}\n.prod-layout .mlist .mrow:hover { background: var(--mj-bg-surface-hover); }\n.prod-layout .mlist .mrow.sel { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n.prod-layout .mlist .mrow .ico {\n width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 13px; flex: 0 0 auto;\n}\n.prod-layout .mlist .mrow .nm { font-weight: 640; font-size: 14px; color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.prod-layout .mlist .mrow .ln2 { margin-top: 2px; }\n.prod-layout .mlist .mrow .meta { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex: 0 0 auto; }\n\n/* deploy-state icon colors (master + detail) */\n.st-bound { background: var(--mj-status-success); }\n.st-scheduled { background: var(--mj-status-info); }\n.st-idle { background: var(--mj-text-disabled); }\n\n/* detail \u2014 own scroll column */\n.prod-layout .detail {\n min-height: 0;\n overflow-y: auto;\n align-self: stretch;\n height: 100%;\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.prod-layout .detail .dh { display: flex; align-items: center; gap: 13px; }\n.prod-layout .detail .dh h2 { margin: 0; font-size: 17px; font-weight: 680; color: var(--mj-text-primary); }\n.prod-layout .detail .dh .sub { margin-top: 3px; }\n.prod-layout .detail .big-ico {\n width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 16px; flex: 0 0 auto;\n}\n\n/* binding rows */\n.bind-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--mj-border-subtle); }\n.bind-row:last-child { border-bottom: none; }\n\n/* run history table */\n.runs-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.runs-table th {\n text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default);\n}\n.runs-table td { padding: 7px 8px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-secondary); }\n.runs-table tr:last-child td { border-bottom: none; }\n.runs-table tr.run-row { cursor: pointer; }\n.runs-table tr.run-row:hover td { background: var(--mj-bg-surface-hover); }\n.runs-table .run-right { text-align: right; white-space: nowrap; }\n.runs-table .run-right i { margin-left: 8px; opacity: .5; }\n\n.run-back {\n display: inline-flex; align-items: center; gap: 6px; cursor: pointer;\n background: none; border: none; color: var(--mj-text-link); font-size: 13px; padding: 0 0 10px;\n}\n\n/* collapsible cards and focus mode */\n.prod-header-card.collapsed {\n padding: 0;\n overflow: visible;\n}\n\n.dh-compact {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 14px;\n min-height: 40px;\n box-sizing: border-box;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.dh-compact:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.dh-compact .mini-ico {\n width: 24px;\n height: 24px;\n border-radius: 6px;\n display: grid;\n place-items: center;\n color: var(--mj-text-inverse);\n font-size: 11px;\n flex: 0 0 auto;\n}\n\n.dh-compact .compact-info {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n line-height: 1.4;\n}\n\n.dh-compact .compact-info strong {\n color: var(--mj-text-primary);\n font-size: 13px;\n font-weight: 600;\n}\n\n.prod-deployment-card.collapsed {\n background: var(--mj-bg-surface-card);\n}\n\n.prod-deployment-card.collapsed .ps-card-head {\n min-height: 40px;\n padding: 6px 14px;\n box-sizing: border-box;\n}\n\n.prod-deployment-card .ps-card-head.clickable {\n cursor: pointer;\n user-select: none;\n transition: background-color 0.15s ease;\n}\n\n.prod-deployment-card .ps-card-head.clickable:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.prod-layout .detail.focused-run {\n gap: 8px;\n}\n\n.run-card.focus-fill {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.run-card.focus-fill .run-card-body {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.ps-card-collapse-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: var(--mj-radius-sm, 6px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.15s ease;\n padding: 0;\n flex: 0 0 auto;\n}\n\n.ps-card-collapse-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n.ps-focus-toggle-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: var(--mj-radius-sm, 6px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.ps-focus-toggle-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n.ps-focus-toggle-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.run-drill-nav {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n}\n\n/* empty state CTA spacing (shared .ps-empty) */\n.ps-production .ps-empty p { max-width: 520px; }\n\n"], encapsulation: 2 });
|
|
668
879
|
}
|
|
669
880
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PSProductionComponent, [{
|
|
670
881
|
type: Component,
|
|
671
|
-
args: [{ standalone: true, selector: 'ps-production', imports: [CommonModule, SharedGenericModule, MJButtonDirective, PSOperateDialogComponent], encapsulation: ViewEncapsulation.None, template: `
|
|
882
|
+
args: [{ standalone: true, selector: 'ps-production', imports: [CommonModule, AngularSplitModule, SharedGenericModule, MJButtonDirective, PSOperateDialogComponent, PSPredictionsGridComponent], encapsulation: ViewEncapsulation.None, template: `
|
|
672
883
|
<div class="ps-panel ps-production" data-testid="ps-production-panel">
|
|
673
884
|
@if (models.length === 0) {
|
|
674
885
|
<div class="ps-empty" data-testid="ps-production-empty">
|
|
@@ -681,137 +892,207 @@ export class PSProductionComponent extends BaseAngularComponent {
|
|
|
681
892
|
</div>
|
|
682
893
|
} @else {
|
|
683
894
|
<!-- KPI strip -->
|
|
684
|
-
|
|
685
|
-
<div class="
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
<div class="prod-layout">
|
|
692
|
-
<!-- master list -->
|
|
693
|
-
<div class="ps-card mlist" data-testid="ps-production-list">
|
|
694
|
-
<div class="ps-card-head"><h3>Published models</h3><span class="ps-badge gray">{{ models.length }}</span></div>
|
|
695
|
-
<div class="ps-card-body" style="padding:8px">
|
|
696
|
-
@for (m of models; track m.modelId) {
|
|
697
|
-
<div class="mrow" data-testid="ps-production-row" [class.sel]="m.modelId === selectedModelId" (click)="select(m.modelId)">
|
|
698
|
-
<div class="ico" [class]="'st-' + m.deployState"><i [class]="deployIcon(m.deployState)"></i></div>
|
|
699
|
-
<div style="flex:1;min-width:0">
|
|
700
|
-
<div class="nm">{{ m.label }}</div>
|
|
701
|
-
<div class="ln2 ps-muted ps-small">v{{ m.version }} · {{ m.algorithm }}</div>
|
|
702
|
-
</div>
|
|
703
|
-
<div class="meta">
|
|
704
|
-
<span class="ps-badge" [class]="deployBadge(m.deployState)">{{ deployLabel(m.deployState) }}</span>
|
|
705
|
-
<div class="ps-mono ps-small ps-muted">{{ m.holdoutMetric }}</div>
|
|
706
|
-
</div>
|
|
707
|
-
</div>
|
|
708
|
-
}
|
|
709
|
-
</div>
|
|
895
|
+
@if (!isRunFocused) {
|
|
896
|
+
<div class="prod-kpis" data-testid="ps-production-kpis">
|
|
897
|
+
<div class="ps-kpi"><div class="label">Published</div><div class="val">{{ models.length }}</div></div>
|
|
898
|
+
<div class="ps-kpi"><div class="label">Scheduled</div><div class="val">{{ scheduledModelCount }}</div></div>
|
|
899
|
+
<div class="ps-kpi"><div class="label">Bound (write-back)</div><div class="val">{{ boundModelCount }}</div></div>
|
|
900
|
+
<div class="ps-kpi"><div class="label">Idle</div><div class="val">{{ idleModelCount }}</div></div>
|
|
710
901
|
</div>
|
|
902
|
+
}
|
|
711
903
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
<div class="ps-
|
|
715
|
-
<
|
|
716
|
-
<
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
<div class="ps-muted ps-small sub">{{ selected.algorithm }} · {{ selected.problemType }} · holdout {{ selected.holdoutMetric }}</div>
|
|
720
|
-
</div>
|
|
721
|
-
<span class="ps-badge" [class]="deployBadge(selected.deployState)">{{ deployLabel(selected.deployState) }}</span>
|
|
722
|
-
<button mjButton variant="primary" size="sm" data-testid="ps-production-operate" (click)="operateOpen = true">
|
|
723
|
-
<i class="fa-solid fa-rocket"></i> Operate
|
|
724
|
-
</button>
|
|
725
|
-
</div>
|
|
904
|
+
<div class="prod-layout" [class.list-collapsed]="isListCollapsed">
|
|
905
|
+
@if (isListCollapsed) {
|
|
906
|
+
<div class="prod-collapsed-strip" data-testid="ps-production-collapsed-rail">
|
|
907
|
+
<button class="prod-rail-collapse" type="button" (click)="toggleList()" aria-label="Expand models list" title="Expand list">
|
|
908
|
+
<i class="fa-solid fa-chevron-right"></i>
|
|
909
|
+
</button>
|
|
910
|
+
<div class="prod-collapsed-strip-label"><i class="fa-solid fa-satellite-dish"></i></div>
|
|
726
911
|
</div>
|
|
912
|
+
}
|
|
727
913
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
<
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
914
|
+
<as-split direction="horizontal" class="prod-splitter" unit="percent" [gutterSize]="6" (dragEnd)="onSplitDragEnd($event.sizes)">
|
|
915
|
+
@if (!isListCollapsed) {
|
|
916
|
+
<as-split-area [size]="listSizePct" [minSize]="18" [maxSize]="50">
|
|
917
|
+
<!-- master list -->
|
|
918
|
+
<div class="ps-card mlist" data-testid="ps-production-list">
|
|
919
|
+
<div class="ps-card-head">
|
|
920
|
+
<h3>Published models</h3>
|
|
921
|
+
<div style="display:flex;gap:6px;align-items:center">
|
|
922
|
+
<span class="ps-badge gray">{{ models.length }}</span>
|
|
923
|
+
<button class="prod-collapse-btn" type="button" (click)="toggleList()" title="Collapse list" aria-label="Collapse list">
|
|
924
|
+
<i class="fa-solid fa-chevron-left"></i>
|
|
925
|
+
</button>
|
|
926
|
+
</div>
|
|
738
927
|
</div>
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
928
|
+
<div class="ps-card-body" style="padding:8px">
|
|
929
|
+
@for (m of models; track m.modelId) {
|
|
930
|
+
<div class="mrow" data-testid="ps-production-row" [class.sel]="m.modelId === selectedModelId" (click)="select(m.modelId)">
|
|
931
|
+
<div class="ico" [class]="'st-' + m.deployState"><i [class]="deployIcon(m.deployState)"></i></div>
|
|
932
|
+
<div style="flex:1;min-width:0">
|
|
933
|
+
<div class="nm">{{ m.label }}</div>
|
|
934
|
+
<div class="ln2 ps-muted ps-small">v{{ m.version }} · {{ m.algorithm }}</div>
|
|
935
|
+
</div>
|
|
936
|
+
<div class="meta">
|
|
937
|
+
<span class="ps-badge" [class]="deployBadge(m.deployState)">{{ deployLabel(m.deployState) }}</span>
|
|
938
|
+
<div class="ps-mono ps-small ps-muted">{{ m.holdoutMetric }}</div>
|
|
748
939
|
</div>
|
|
749
|
-
<span class="ps-badge" [class]="modeBadge(b.mode)">{{ b.mode }}</span>
|
|
750
940
|
</div>
|
|
751
941
|
}
|
|
942
|
+
</div>
|
|
943
|
+
</div>
|
|
944
|
+
</as-split-area>
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
<as-split-area [size]="isListCollapsed ? 100 : detailSizePct" [minSize]="50">
|
|
948
|
+
<!-- detail -->
|
|
949
|
+
<div class="ps-col detail" [class.focused-run]="selectedRunId && isRunFocused" data-testid="ps-production-detail">
|
|
950
|
+
<!-- 1. MODEL HEADER CARD -->
|
|
951
|
+
<div class="ps-card prod-header-card" [class.collapsed]="isHeaderCollapsed">
|
|
952
|
+
@if (!isHeaderCollapsed) {
|
|
953
|
+
<div class="ps-card-body dh">
|
|
954
|
+
<div class="big-ico" [class]="'st-' + selected.deployState"><i [class]="deployIcon(selected.deployState)"></i></div>
|
|
955
|
+
<div style="flex:1;min-width:0">
|
|
956
|
+
<h2 data-testid="ps-production-detail-name">{{ selected.label }} <span class="ps-tag ps-mono">v{{ selected.version }}</span></h2>
|
|
957
|
+
<div class="ps-muted ps-small sub">{{ selected.algorithm }} · {{ selected.problemType }} · holdout {{ selected.holdoutMetric }}</div>
|
|
958
|
+
</div>
|
|
959
|
+
<span class="ps-badge" [class]="deployBadge(selected.deployState)">{{ deployLabel(selected.deployState) }}</span>
|
|
960
|
+
<button mjButton variant="primary" size="sm" data-testid="ps-production-operate" (click)="operateOpen = true">
|
|
961
|
+
<i class="fa-solid fa-rocket"></i> Operate
|
|
962
|
+
</button>
|
|
963
|
+
<button class="ps-card-collapse-btn" type="button" (click)="toggleHeaderCollapse()" title="Collapse model header" aria-label="Collapse model header">
|
|
964
|
+
<i class="fa-solid fa-chevron-up"></i>
|
|
965
|
+
</button>
|
|
966
|
+
</div>
|
|
752
967
|
} @else {
|
|
753
|
-
<div class="ps-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
968
|
+
<div class="ps-card-body dh-compact" (click)="toggleHeaderCollapse()">
|
|
969
|
+
<div class="mini-ico" [class]="'st-' + selected.deployState"><i [class]="deployIcon(selected.deployState)"></i></div>
|
|
970
|
+
<div class="compact-info">
|
|
971
|
+
<strong>{{ selected.label }}</strong>
|
|
972
|
+
<span class="ps-tag ps-mono ps-small">v{{ selected.version }}</span>
|
|
973
|
+
<span class="ps-muted ps-small">· {{ selected.algorithm }}</span>
|
|
974
|
+
</div>
|
|
975
|
+
<span class="ps-badge" [class]="deployBadge(selected.deployState)">{{ deployLabel(selected.deployState) }}</span>
|
|
976
|
+
<button mjButton variant="primary" size="sm" data-testid="ps-production-operate-compact" (click)="$event.stopPropagation(); operateOpen = true">
|
|
977
|
+
<i class="fa-solid fa-rocket"></i> Operate
|
|
978
|
+
</button>
|
|
979
|
+
<button class="ps-card-collapse-btn" type="button" (click)="$event.stopPropagation(); toggleHeaderCollapse()" title="Expand model header" aria-label="Expand model header">
|
|
980
|
+
<i class="fa-solid fa-chevron-down"></i>
|
|
981
|
+
</button>
|
|
982
|
+
</div>
|
|
758
983
|
}
|
|
759
|
-
|
|
760
|
-
</div>
|
|
761
|
-
</div>
|
|
984
|
+
</div>
|
|
762
985
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
986
|
+
<!-- 2. DEPLOYMENT STATUS CARD -->
|
|
987
|
+
<div class="ps-card prod-deployment-card" [class.collapsed]="isDeploymentCollapsed">
|
|
988
|
+
<div class="ps-card-head clickable" (click)="toggleDeploymentCollapse()">
|
|
989
|
+
<div style="display:flex;align-items:center;gap:8px">
|
|
990
|
+
<i class="fa-solid fa-network-wired" style="color:var(--mj-brand-primary)"></i>
|
|
991
|
+
<h3>Deployment</h3>
|
|
992
|
+
<span class="ps-muted ps-small">{{ selected.processCount }} process{{ selected.processCount === 1 ? '' : 'es' }} · {{ selected.bindingCount }} binding{{ selected.bindingCount === 1 ? '' : 's' }}</span>
|
|
993
|
+
@if (isDeploymentCollapsed && selectedBindings.length > 0) {
|
|
994
|
+
<span class="ps-badge gray ps-small">{{ selectedBindings[0].targetEntity }}.{{ selectedBindings[0].targetColumn }}</span>
|
|
995
|
+
}
|
|
996
|
+
</div>
|
|
997
|
+
<div style="display:flex;align-items:center;gap:6px">
|
|
998
|
+
<button class="ps-card-collapse-btn" type="button" (click)="$event.stopPropagation(); toggleDeploymentCollapse()" [title]="isDeploymentCollapsed ? 'Expand deployment' : 'Collapse deployment'" [attr.aria-label]="isDeploymentCollapsed ? 'Expand deployment' : 'Collapse deployment'">
|
|
999
|
+
<i class="fa-solid" [class.fa-chevron-up]="!isDeploymentCollapsed" [class.fa-chevron-down]="isDeploymentCollapsed"></i>
|
|
1000
|
+
</button>
|
|
1001
|
+
</div>
|
|
1002
|
+
</div>
|
|
1003
|
+
@if (!isDeploymentCollapsed) {
|
|
1004
|
+
<div class="ps-card-body">
|
|
1005
|
+
@if (selected.deployState === 'idle') {
|
|
1006
|
+
<div class="ps-callout info">
|
|
1007
|
+
<i class="fa-solid fa-circle-info"></i>
|
|
1008
|
+
<div class="ps-small">This model is published but <strong>not operating</strong> yet — nothing scores with it. Click <strong>Operate</strong> above to run it now, schedule it to run regularly, or write predictions back to a column.</div>
|
|
1009
|
+
</div>
|
|
1010
|
+
} @else {
|
|
1011
|
+
@if (selectedBindings.length > 0) {
|
|
1012
|
+
<div class="ps-section-title">Scoring bindings</div>
|
|
1013
|
+
@for (b of selectedBindings; track b.id) {
|
|
1014
|
+
<div class="bind-row">
|
|
1015
|
+
<i class="fa-solid fa-arrow-right-to-bracket ps-muted"></i>
|
|
1016
|
+
<div style="flex:1">
|
|
1017
|
+
<div class="ps-small"><strong>{{ b.targetEntity }}</strong>.{{ b.targetColumn }}</div>
|
|
1018
|
+
<div class="ps-muted ps-small">{{ b.mode }}{{ b.schedulePhrase ? ' · ' + b.schedulePhrase : '' }}</div>
|
|
1019
|
+
</div>
|
|
1020
|
+
<span class="ps-badge" [class]="modeBadge(b.mode)">{{ b.mode }}</span>
|
|
1021
|
+
</div>
|
|
1022
|
+
}
|
|
1023
|
+
} @else {
|
|
1024
|
+
<div class="ps-small ps-muted">Scheduled to run, writing generic output to the process run history (no write-back column).</div>
|
|
1025
|
+
}
|
|
1026
|
+
@if (selected.lastScoredAt) {
|
|
1027
|
+
<div class="ps-divider"></div>
|
|
1028
|
+
<div class="ps-row" style="justify-content:space-between"><span class="ps-muted ps-small">Last scored</span><span class="ps-small">{{ selected.lastScoredAt | date:'medium' }}{{ selected.lastRowCount != null ? ' · ' + selected.lastRowCount + ' rows' : '' }}</span></div>
|
|
787
1029
|
}
|
|
788
|
-
</tbody>
|
|
789
|
-
</table>
|
|
790
|
-
}
|
|
791
|
-
} @else if (loadingRuns) {
|
|
792
|
-
<mj-loading text="Loading runs..." size="small"></mj-loading>
|
|
793
|
-
} @else if (runs.length === 0) {
|
|
794
|
-
<div class="ps-small ps-muted">No runs recorded yet. Each time this model runs as a Record Process, its predictions are saved to the process run history — even without a scoring binding.</div>
|
|
795
|
-
} @else {
|
|
796
|
-
<table class="runs-table">
|
|
797
|
-
<thead><tr><th>When</th><th>Status</th><th>Scored</th><th>Process</th><th></th></tr></thead>
|
|
798
|
-
<tbody>
|
|
799
|
-
@for (r of runs; track r.ID) {
|
|
800
|
-
<tr data-testid="ps-production-run" class="run-row" (click)="openRun(r.ID)">
|
|
801
|
-
<td>{{ (r.StartTime || r.CreatedAt) | date:'short' }}</td>
|
|
802
|
-
<td><span class="ps-badge" [class]="runBadge(r.Status)">{{ r.Status }}</span></td>
|
|
803
|
-
<td class="ps-mono">{{ r.SuccessCount }}<span class="ps-muted">/{{ r.TotalItemCount ?? 0 }}</span></td>
|
|
804
|
-
<td class="ps-small ps-muted">{{ r.ProcessName || '—' }}</td>
|
|
805
|
-
<td class="run-right">@if (r.DryRun) { <span class="ps-tag amber">dry run</span> }<i class="fa-solid fa-chevron-right ps-muted"></i></td>
|
|
806
|
-
</tr>
|
|
807
1030
|
}
|
|
808
|
-
</
|
|
809
|
-
|
|
810
|
-
|
|
1031
|
+
</div>
|
|
1032
|
+
}
|
|
1033
|
+
</div>
|
|
1034
|
+
|
|
1035
|
+
<!-- 3. RUN HISTORY CARD -->
|
|
1036
|
+
<div class="ps-card run-card" [class.drilldown-active]="selectedRunId" [class.focus-fill]="selectedRunId && isRunFocused">
|
|
1037
|
+
<div class="ps-card-head">
|
|
1038
|
+
<div style="display:flex;align-items:center;gap:8px">
|
|
1039
|
+
<i class="fa-solid fa-clock-rotate-left" style="color:var(--mj-status-info)"></i>
|
|
1040
|
+
<h3>Run history</h3>
|
|
1041
|
+
<span class="ps-muted ps-small">last 90 days · newest first</span>
|
|
1042
|
+
</div>
|
|
1043
|
+
@if (selectedRunId) {
|
|
1044
|
+
<div style="display:flex;align-items:center;gap:8px">
|
|
1045
|
+
<button class="ps-focus-toggle-btn" type="button" (click)="toggleRunFocus()" [class.active]="isRunFocused" [title]="isRunFocused ? 'Exit focus (expand header & deployment)' : 'Focus mode (collapse header & deployment)'">
|
|
1046
|
+
<i class="fa-solid" [class.fa-compress]="isRunFocused" [class.fa-expand]="!isRunFocused"></i>
|
|
1047
|
+
<span>{{ isRunFocused ? 'Exit Focus' : 'Focus' }}</span>
|
|
1048
|
+
</button>
|
|
1049
|
+
</div>
|
|
1050
|
+
}
|
|
1051
|
+
</div>
|
|
1052
|
+
<div class="ps-card-body run-card-body">
|
|
1053
|
+
@if (selectedRunId) {
|
|
1054
|
+
<!-- run drill-in: unified predictions grid with virtual scrolling, name resolution, charts & history -->
|
|
1055
|
+
<div class="run-drill-nav">
|
|
1056
|
+
<button class="run-back" data-testid="ps-production-run-back" (click)="closeRun()">
|
|
1057
|
+
<i class="fa-solid fa-arrow-left"></i> All runs
|
|
1058
|
+
</button>
|
|
1059
|
+
<span class="ps-tag ps-mono ps-small">Run: {{ selectedRunId }}</span>
|
|
1060
|
+
</div>
|
|
1061
|
+
<ps-predictions-grid
|
|
1062
|
+
data-testid="ps-production-run-grid"
|
|
1063
|
+
[modelId]="selected.modelId"
|
|
1064
|
+
[runId]="selectedRunId"
|
|
1065
|
+
[entityName]="selectedTargetEntityName"
|
|
1066
|
+
[problemType]="selected.problemType"
|
|
1067
|
+
[title]="selected.label + ' — Run Predictions'"
|
|
1068
|
+
[height]="runGridHeight">
|
|
1069
|
+
</ps-predictions-grid>
|
|
1070
|
+
} @else if (loadingRuns) {
|
|
1071
|
+
<mj-loading text="Loading runs..." size="small"></mj-loading>
|
|
1072
|
+
} @else if (runs.length === 0) {
|
|
1073
|
+
<div class="ps-small ps-muted">No runs recorded yet. Each time this model runs as a Record Process, its predictions are saved to the process run history — even without a scoring binding.</div>
|
|
1074
|
+
} @else {
|
|
1075
|
+
<table class="runs-table">
|
|
1076
|
+
<thead><tr><th>When</th><th>Status</th><th>Scored</th><th>Process</th><th></th></tr></thead>
|
|
1077
|
+
<tbody>
|
|
1078
|
+
@for (r of runs; track r.ID) {
|
|
1079
|
+
<tr data-testid="ps-production-run" class="run-row" (click)="openRun(r.ID)">
|
|
1080
|
+
<td>{{ (r.StartTime || r.CreatedAt) | date:'short' }}</td>
|
|
1081
|
+
<td><span class="ps-badge" [class]="runBadge(r.Status)">{{ r.Status }}</span></td>
|
|
1082
|
+
<td class="ps-mono">{{ r.SuccessCount }}<span class="ps-muted">/{{ r.TotalItemCount ?? 0 }}</span></td>
|
|
1083
|
+
<td class="ps-small ps-muted">{{ r.ProcessName || '—' }}</td>
|
|
1084
|
+
<td class="run-right">@if (r.DryRun) { <span class="ps-tag amber">dry run</span> }<i class="fa-solid fa-chevron-right ps-muted"></i></td>
|
|
1085
|
+
</tr>
|
|
1086
|
+
}
|
|
1087
|
+
</tbody>
|
|
1088
|
+
</table>
|
|
1089
|
+
}
|
|
1090
|
+
</div>
|
|
1091
|
+
</div>
|
|
811
1092
|
</div>
|
|
812
|
-
</
|
|
813
|
-
</
|
|
814
|
-
|
|
1093
|
+
</as-split-area>
|
|
1094
|
+
</as-split>
|
|
1095
|
+
</div>
|
|
815
1096
|
|
|
816
1097
|
<ps-operate-dialog
|
|
817
1098
|
[Visible]="operateOpen"
|
|
@@ -824,9 +1105,9 @@ export class PSProductionComponent extends BaseAngularComponent {
|
|
|
824
1105
|
</ps-operate-dialog>
|
|
825
1106
|
}
|
|
826
1107
|
</div>
|
|
827
|
-
`, styles: ["/* ============================================================================\n Predictive Studio \u2014 shared panel styles (design-token compliant)\n Maps the mockup design system onto MemberJunction semantic --mj-* tokens.\n Loaded by every PS panel component (styleUrls) under ViewEncapsulation.None,\n so the class names are global within the PS dashboard subtree.\n No hardcoded colors except the intentional categorical node/algorithm palette\n (declared once as --ps-* custom props below) which must stay distinct across\n light/dark to remain readable as diagram accents.\n ============================================================================ */\n\n/* Categorical accents for DAG node types + algorithm chips. These are\n data-visualization colors that must remain distinct regardless of theme\n (allowed exception #3 in the design-token rules). */\n.ps-panel {\n --ps-node-source: #6b7280;\n --ps-node-feature: #2050c8;\n --ps-node-embedding: #7b3ff0;\n --ps-node-target: #1f9d57;\n --ps-node-algorithm: #d98213;\n /* budget-gauge categorical accents (reuse the node palette so light/dark stay distinct) */\n --ps-gauge-cost: var(--ps-node-algorithm);\n --ps-gauge-iterations: var(--ps-node-feature);\n}\n\n.ps-panel {\n display: block;\n height: 100%;\n}\n\n/* ---- generic layout helpers ---- */\n.ps-row { display: flex; gap: 16px; }\n.ps-col { display: flex; flex-direction: column; gap: 16px; }\n.ps-wrap { flex-wrap: wrap; }\n.ps-spacer { flex: 1; }\n.ps-muted { color: var(--mj-text-muted); }\n.ps-small { font-size: 12.5px; }\n.ps-mono { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 12.5px; }\n.ps-section-title {\n font-size: 12px; text-transform: uppercase; letter-spacing: .06em;\n color: var(--mj-text-muted); margin: 4px 0 2px; font-weight: 700;\n}\n\n/* ---- cards ---- */\n.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-card-head {\n display: flex; align-items: center; gap: 10px;\n padding: 14px 16px; border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-card-head h3 { font-size: 14.5px; margin: 0; font-weight: 650; color: var(--mj-text-primary); }\n.ps-card-body { padding: 16px; }\n\n/* ---- KPI tiles ---- */\n.ps-kpi {\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 8px; padding: 16px 18px;\n}\n.ps-kpi .label { font-size: 12px; color: var(--mj-text-muted); font-weight: 600; }\n.ps-kpi .val { font-size: 26px; font-weight: 720; letter-spacing: -.02em; margin-top: 2px; color: var(--mj-text-primary); }\n\n/* ---- badges ---- */\n.ps-badge {\n display: inline-flex; align-items: center; gap: 5px;\n padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 650; line-height: 1.7;\n}\n.ps-badge.gray { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.ps-badge.blue { background: var(--mj-status-info-bg); color: var(--mj-status-info-text); }\n.ps-badge.green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n.ps-badge.amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-badge.red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }\n\n/* recommendation-level chips (the ranking matrix payoff) */\n.ps-lvl {\n display: inline-flex; align-items: center; justify-content: center;\n min-width: 92px; padding: 4px 10px; border-radius: 7px;\n font-weight: 650; font-size: 11.5px; color: var(--mj-text-inverse);\n}\n.ps-lvl-Primary { background: var(--mj-status-success); }\n.ps-lvl-Strong { background: var(--mj-status-info); }\n.ps-lvl-Viable { background: var(--mj-status-warning); }\n.ps-lvl-Weak { background: var(--mj-text-disabled); }\n.ps-lvl-NotRecommended { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n/* ---- tags ---- */\n.ps-tag {\n display: inline-block; padding: 2px 8px; border-radius: 6px;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary);\n font-size: 11.5px; font-weight: 600;\n}\n.ps-tag.muted { opacity: .6; }\n.ps-divider { height: 1px; background: var(--mj-border-subtle); margin: 8px 0; }\n\n/* ---- tables ---- */\n.ps-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.ps-table th {\n text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 9px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.ps-table td { padding: 11px 12px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-primary); }\n.ps-table tr:hover td { background: var(--mj-bg-surface-hover); }\n.ps-table .num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.ps-rank {\n width: 22px; height: 22px; border-radius: 6px; background: var(--mj-bg-surface-sunken);\n display: inline-grid; place-items: center; font-weight: 700; font-size: 11.5px; color: var(--mj-text-secondary);\n}\n.ps-rank.gold { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n\n/* ---- progress bars ---- */\n.ps-bar { height: 8px; border-radius: 999px; background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-bar > span { display: block; height: 100%; border-radius: 999px; background: var(--mj-brand-primary); }\n.ps-bar.warn > span { background: var(--mj-status-warning); }\n.ps-bar.run > span { background: var(--mj-brand-primary); }\n\n.ps-fbar { display: grid; grid-template-columns: minmax(150px, 1.3fr) 2fr 56px; align-items: center; gap: 14px; padding: 8px 0; }\n.ps-fbar + .ps-fbar { border-top: 1px solid var(--mj-border-subtle); }\n.ps-fbar .track { height: 10px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-fbar .track > span { display: block; height: 100%; border-radius: var(--mj-radius-full); background: var(--mj-brand-primary); }\n.ps-fbar .track > span.warn { background: var(--mj-status-warning); }\n.ps-fbar .name { color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.ps-fbar > .ps-mono { text-align: right; color: var(--mj-text-secondary); font-variant-numeric: tabular-nums; }\n\n/* gauge */\n.ps-gauge {\n position: relative; width: 64px; height: 64px; border-radius: 50%; flex: 0 0 auto;\n background: conic-gradient(var(--ps-gauge-color, var(--mj-brand-primary)) calc(var(--ps-p, 40) * 1%), var(--mj-bg-surface-sunken) 0);\n display: grid; place-items: center;\n}\n.ps-gauge::after { content: ''; position: absolute; inset: 9px; background: var(--mj-bg-surface); border-radius: 50%; }\n.ps-gauge .g-val { position: relative; font-weight: 720; font-size: 14px; color: var(--mj-text-primary); }\n\n/* warning / info callouts */\n.ps-callout { display: flex; gap: 11px; padding: 12px 14px; border-radius: 10px; border: 1px solid; }\n.ps-callout.warn { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); color: var(--mj-status-warning-text); }\n.ps-callout.info { background: var(--mj-status-info-bg); border-color: var(--mj-status-info-border); color: var(--mj-status-info-text); }\n.ps-callout.success { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); color: var(--mj-status-success-text); }\n.ps-callout i { font-size: 16px; margin-top: 1px; }\n\n/* lifecycle stepper */\n.ps-stepper { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }\n.ps-step { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--mj-text-muted); }\n.ps-step .pip {\n width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--mj-border-strong);\n display: grid; place-items: center; font-size: 11px;\n}\n.ps-step.done { color: var(--mj-status-success-text); }\n.ps-step.done .pip { background: var(--mj-status-success); border-color: var(--mj-status-success); color: var(--mj-text-inverse); }\n.ps-step.curr { color: var(--mj-brand-primary); }\n.ps-step.curr .pip { border-color: var(--mj-brand-primary); color: var(--mj-brand-primary); }\n.ps-step .ln { width: 26px; height: 2px; background: var(--mj-border-strong); }\n\n/* ---- DAG flow canvas ---- */\n.ps-flow {\n position: relative;\n background:\n linear-gradient(var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n linear-gradient(90deg, var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default); border-radius: 10px;\n min-height: 620px; overflow: hidden;\n}\n.ps-node {\n position: absolute; width: 190px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong); border-left-width: 3px; border-radius: 8px;\n cursor: pointer;\n}\n.ps-node .nh {\n display: flex; align-items: center; gap: 8px; padding: 9px 11px;\n border-bottom: 1px solid var(--mj-border-subtle); font-weight: 650; font-size: 12.5px; color: var(--mj-text-primary);\n}\n.ps-node .nh i.tile {\n width: 24px; height: 24px; border-radius: 6px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 12px; flex: 0 0 auto;\n}\n.ps-node .nh .ps-tag { margin-left: auto; }\n.ps-node .nb { padding: 9px 11px; font-size: 12px; color: var(--mj-text-secondary); }\n.ps-node .nb-row { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; }\n.ps-node .nb-row .k { color: var(--mj-text-muted); }\n.ps-node.src { border-left-color: var(--ps-node-source); }\n.ps-node.src .nh i.tile { background: var(--ps-node-source); }\n.ps-node.feat { border-left-color: var(--ps-node-feature); }\n.ps-node.feat .nh i.tile { background: var(--ps-node-feature); }\n.ps-node.emb { border-left-color: var(--ps-node-embedding); }\n.ps-node.emb .nh i.tile { background: var(--ps-node-embedding); }\n.ps-node.target { border-left-color: var(--ps-node-target); }\n.ps-node.target .nh i.tile { background: var(--ps-node-target); }\n.ps-node.algo { border-left-color: var(--ps-node-algorithm); }\n.ps-node.algo .nh i.tile { background: var(--ps-node-algorithm); }\n.ps-node.output { border-left-color: var(--mj-status-success); }\n.ps-node.output .nh i.tile { background: var(--mj-status-success); }\n.ps-node.selected {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n.ps-node .port {\n position: absolute; width: 11px; height: 11px; border-radius: 50%;\n background: var(--mj-bg-surface); border: 2px solid var(--mj-brand-primary);\n top: 50%; transform: translateY(-50%);\n}\n.ps-node .port.in { left: -6px; }\n.ps-node .port.out { right: -6px; }\nsvg.ps-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }\nsvg.ps-edges path { stroke: color-mix(in srgb, var(--mj-brand-primary) 45%, transparent); stroke-width: 2; fill: none; }\n\n/* palette chips */\n.ps-pchip {\n display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border-radius: 8px;\n border: 1px dashed var(--mj-border-strong); background: var(--mj-bg-surface);\n font-size: 12.5px; font-weight: 600; color: var(--mj-text-secondary); cursor: grab;\n}\n.ps-pchip i { font-size: 12px; color: var(--mj-text-inverse); width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center; }\n.ps-pchip.s i { background: var(--ps-node-source); }\n.ps-pchip.f i { background: var(--ps-node-feature); }\n.ps-pchip.e i { background: var(--ps-node-embedding); }\n.ps-pchip.t i { background: var(--ps-node-target); }\n.ps-pchip.a i { background: var(--ps-node-algorithm); }\n\n/* segmented control */\n.ps-seg { display: inline-flex; border: 1px solid var(--mj-border-default); border-radius: 8px; overflow: hidden; }\n.ps-seg button {\n border: none; background: var(--mj-bg-surface); color: var(--mj-text-secondary);\n padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer;\n border-right: 1px solid var(--mj-border-default);\n}\n.ps-seg button:last-child { border-right: none; }\n.ps-seg button.on { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n\n/* field control */\n.ps-field { margin-bottom: 14px; }\n.ps-field > label {\n display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; margin-bottom: 6px;\n}\n.ps-input {\n width: 100%; padding: 8px 10px; border: 1px solid var(--mj-border-default);\n border-radius: 6px; font-size: 13px; background: var(--mj-bg-surface); color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n.ps-input:focus { outline: none; border-color: var(--mj-brand-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); }\n\n/* loading container */\n.ps-loading { display: flex; align-items: center; justify-content: center; padding: 60px 0; }\n\n/* ---- empty / prompt states ---- */\n.ps-empty {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n text-align: center; gap: 10px; padding: 56px 24px; color: var(--mj-text-muted);\n}\n.ps-empty .ps-empty-ico {\n width: 60px; height: 60px; border-radius: 16px; display: grid; place-items: center;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-disabled); font-size: 24px;\n}\n.ps-empty h3 { margin: 4px 0 0; font-size: 16px; font-weight: 650; color: var(--mj-text-secondary); }\n.ps-empty p { margin: 0; max-width: 420px; font-size: 13px; line-height: 1.5; }\n\n/* ---- confirm modal ---- */\n.ps-modal-backdrop {\n position: fixed; inset: 0; z-index: 1000;\n background: var(--mj-bg-overlay);\n display: flex; align-items: center; justify-content: center; padding: 24px;\n}\n.ps-modal {\n width: 100%; max-width: 480px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default); border-radius: 14px;\n box-shadow: var(--mj-shadow-lg, var(--mj-shadow-sm)); overflow: hidden;\n}\n.ps-modal-head {\n display: flex; align-items: center; gap: 12px; padding: 18px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-modal-head .ico {\n width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;\n font-size: 16px; flex: 0 0 auto;\n background: var(--mj-status-info-bg); color: var(--mj-status-info-text);\n}\n.ps-modal-head.warn .ico { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-modal-head.danger .ico { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-modal-head h3 { margin: 0; font-size: 15.5px; font-weight: 650; color: var(--mj-text-primary); }\n.ps-modal-body { padding: 18px 20px; font-size: 13.5px; line-height: 1.55; color: var(--mj-text-secondary); }\n.ps-modal-body .ps-field { margin-top: 14px; margin-bottom: 0; }\n.ps-modal-foot {\n display: flex; align-items: center; gap: 10px; padding: 14px 20px;\n border-top: 1px solid var(--mj-border-subtle); background: var(--mj-bg-surface-card);\n}\n.ps-modal-foot .ps-spacer { flex: 1; }\n", "/* Models in Production \u2014 model-centric control tower (master/detail). All colors via --mj-* tokens. */\n\n.ps-production {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 4px;\n}\n\n.prod-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 14px;\n}\n\n.prod-layout {\n display: grid;\n grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);\n gap: 16px;\n align-items: start;\n}\n@media (max-width: 900px) {\n .prod-layout { grid-template-columns: 1fr; }\n}\n\n/* master list */\n.prod-layout .mlist .mrow {\n display: flex;\n align-items: center;\n gap: 11px;\n padding: 10px 10px;\n border-radius: 9px;\n cursor: pointer;\n}\n.prod-layout .mlist .mrow:hover { background: var(--mj-bg-surface-hover); }\n.prod-layout .mlist .mrow.sel { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n.prod-layout .mlist .mrow .ico {\n width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 13px; flex: 0 0 auto;\n}\n.prod-layout .mlist .mrow .nm { font-weight: 640; font-size: 14px; color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.prod-layout .mlist .mrow .ln2 { margin-top: 2px; }\n.prod-layout .mlist .mrow .meta { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex: 0 0 auto; }\n\n/* deploy-state icon colors (master + detail) */\n.st-bound { background: var(--mj-status-success); }\n.st-scheduled { background: var(--mj-status-info); }\n.st-idle { background: var(--mj-text-disabled); }\n\n/* detail */\n.prod-layout .detail { display: flex; flex-direction: column; gap: 14px; }\n.prod-layout .detail .dh { display: flex; align-items: center; gap: 13px; }\n.prod-layout .detail .dh h2 { margin: 0; font-size: 17px; font-weight: 680; color: var(--mj-text-primary); }\n.prod-layout .detail .dh .sub { margin-top: 3px; }\n.prod-layout .detail .big-ico {\n width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 16px; flex: 0 0 auto;\n}\n\n/* binding rows */\n.bind-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--mj-border-subtle); }\n.bind-row:last-child { border-bottom: none; }\n\n/* run history table */\n.runs-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.runs-table th {\n text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default);\n}\n.runs-table td { padding: 7px 8px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-secondary); }\n.runs-table tr:last-child td { border-bottom: none; }\n.runs-table tr.run-row { cursor: pointer; }\n.runs-table tr.run-row:hover td { background: var(--mj-bg-surface-hover); }\n.runs-table .run-right { text-align: right; white-space: nowrap; }\n.runs-table .run-right i { margin-left: 8px; opacity: .5; }\n\n.run-back {\n display: inline-flex; align-items: center; gap: 6px; cursor: pointer;\n background: none; border: none; color: var(--mj-text-link); font-size: 13px; padding: 0 0 10px;\n}\n\n/* empty state CTA spacing (shared .ps-empty) */\n.ps-production .ps-empty p { max-width: 520px; }\n"] }]
|
|
1108
|
+
`, styles: ["/* ============================================================================\n Predictive Studio \u2014 shared panel styles (design-token compliant)\n Maps the mockup design system onto MemberJunction semantic --mj-* tokens.\n Loaded by every PS panel component (styleUrls) under ViewEncapsulation.None,\n so the class names are global within the PS dashboard subtree.\n No hardcoded colors except the intentional categorical node/algorithm palette\n (declared once as --ps-* custom props below) which must stay distinct across\n light/dark to remain readable as diagram accents.\n ============================================================================ */\n\n/* Categorical accents for DAG node types + algorithm chips. These are\n data-visualization colors that must remain distinct regardless of theme\n (allowed exception #3 in the design-token rules). */\n.ps-panel {\n --ps-node-source: #6b7280;\n --ps-node-feature: #2050c8;\n --ps-node-embedding: #7b3ff0;\n --ps-node-target: #1f9d57;\n --ps-node-algorithm: #d98213;\n /* budget-gauge categorical accents (reuse the node palette so light/dark stay distinct) */\n --ps-gauge-cost: var(--ps-node-algorithm);\n --ps-gauge-iterations: var(--ps-node-feature);\n}\n\n.ps-panel {\n display: block;\n height: 100%;\n}\n\n/* ---- generic layout helpers ---- */\n.ps-row { display: flex; gap: 16px; }\n.ps-col { display: flex; flex-direction: column; gap: 16px; }\n.ps-wrap { flex-wrap: wrap; }\n.ps-spacer { flex: 1; }\n.ps-muted { color: var(--mj-text-muted); }\n.ps-small { font-size: 12.5px; }\n.ps-mono { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 12.5px; }\n.ps-section-title {\n font-size: 12px; text-transform: uppercase; letter-spacing: .06em;\n color: var(--mj-text-muted); margin: 4px 0 2px; font-weight: 700;\n}\n\n/* ---- cards ---- */\n.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-card-head {\n display: flex; align-items: center; gap: 10px;\n padding: 14px 16px; border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-card-head h3 { font-size: 14.5px; margin: 0; font-weight: 650; color: var(--mj-text-primary); }\n.ps-card-body { padding: 16px; }\n\n/* ---- KPI tiles ---- */\n.ps-kpi {\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 8px; padding: 16px 18px;\n}\n.ps-kpi .label { font-size: 12px; color: var(--mj-text-muted); font-weight: 600; }\n.ps-kpi .val { font-size: 26px; font-weight: 720; letter-spacing: -.02em; margin-top: 2px; color: var(--mj-text-primary); }\n\n/* ---- badges ---- */\n.ps-badge {\n display: inline-flex; align-items: center; gap: 5px;\n padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 650; line-height: 1.7;\n}\n.ps-badge.gray { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.ps-badge.blue { background: var(--mj-status-info-bg); color: var(--mj-status-info-text); }\n.ps-badge.green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n.ps-badge.amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-badge.red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }\n\n/* recommendation-level chips (the ranking matrix payoff) */\n.ps-lvl {\n display: inline-flex; align-items: center; justify-content: center;\n min-width: 92px; padding: 4px 10px; border-radius: 7px;\n font-weight: 650; font-size: 11.5px; color: var(--mj-text-inverse);\n}\n.ps-lvl-Primary { background: var(--mj-status-success); }\n.ps-lvl-Strong { background: var(--mj-status-info); }\n.ps-lvl-Viable { background: var(--mj-status-warning); }\n.ps-lvl-Weak { background: var(--mj-text-disabled); }\n.ps-lvl-NotRecommended { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n/* ---- tags ---- */\n.ps-tag {\n display: inline-block; padding: 2px 8px; border-radius: 6px;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary);\n font-size: 11.5px; font-weight: 600;\n}\n.ps-tag.muted { opacity: .6; }\n.ps-divider { height: 1px; background: var(--mj-border-subtle); margin: 8px 0; }\n\n/* ---- tables ---- */\n.ps-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.ps-table th {\n text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 9px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.ps-table td { padding: 11px 12px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-primary); }\n.ps-table tr:hover td { background: var(--mj-bg-surface-hover); }\n.ps-table .num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.ps-rank {\n width: 22px; height: 22px; border-radius: 6px; background: var(--mj-bg-surface-sunken);\n display: inline-grid; place-items: center; font-weight: 700; font-size: 11.5px; color: var(--mj-text-secondary);\n}\n.ps-rank.gold { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n\n/* ---- progress bars ---- */\n.ps-bar { height: 8px; border-radius: 999px; background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-bar > span { display: block; height: 100%; border-radius: 999px; background: var(--mj-brand-primary); }\n.ps-bar.warn > span { background: var(--mj-status-warning); }\n.ps-bar.run > span { background: var(--mj-brand-primary); }\n\n.ps-fbar { display: grid; grid-template-columns: minmax(150px, 1.3fr) 2fr 56px; align-items: center; gap: 14px; padding: 8px 0; }\n.ps-fbar + .ps-fbar { border-top: 1px solid var(--mj-border-subtle); }\n.ps-fbar .track { height: 10px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-fbar .track > span { display: block; height: 100%; border-radius: var(--mj-radius-full); background: var(--mj-brand-primary); }\n.ps-fbar .track > span.warn { background: var(--mj-status-warning); }\n.ps-fbar .name { color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.ps-fbar > .ps-mono { text-align: right; color: var(--mj-text-secondary); font-variant-numeric: tabular-nums; }\n\n/* gauge */\n.ps-gauge {\n position: relative; width: 64px; height: 64px; border-radius: 50%; flex: 0 0 auto;\n background: conic-gradient(var(--ps-gauge-color, var(--mj-brand-primary)) calc(var(--ps-p, 40) * 1%), var(--mj-bg-surface-sunken) 0);\n display: grid; place-items: center;\n}\n.ps-gauge::after { content: ''; position: absolute; inset: 9px; background: var(--mj-bg-surface); border-radius: 50%; }\n.ps-gauge .g-val { position: relative; font-weight: 720; font-size: 14px; color: var(--mj-text-primary); }\n\n/* warning / info callouts */\n.ps-callout { display: flex; gap: 11px; padding: 12px 14px; border-radius: 10px; border: 1px solid; }\n.ps-callout.warn { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); color: var(--mj-status-warning-text); }\n.ps-callout.info { background: var(--mj-status-info-bg); border-color: var(--mj-status-info-border); color: var(--mj-status-info-text); }\n.ps-callout.success { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); color: var(--mj-status-success-text); }\n.ps-callout i { font-size: 16px; margin-top: 1px; }\n\n/* lifecycle stepper */\n.ps-stepper { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }\n.ps-step { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--mj-text-muted); }\n.ps-step .pip {\n width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--mj-border-strong);\n display: grid; place-items: center; font-size: 11px;\n}\n.ps-step.done { color: var(--mj-status-success-text); }\n.ps-step.done .pip { background: var(--mj-status-success); border-color: var(--mj-status-success); color: var(--mj-text-inverse); }\n.ps-step.curr { color: var(--mj-brand-primary); }\n.ps-step.curr .pip { border-color: var(--mj-brand-primary); color: var(--mj-brand-primary); }\n.ps-step .ln { width: 26px; height: 2px; background: var(--mj-border-strong); }\n\n/* ---- DAG flow canvas ---- */\n.ps-flow {\n position: relative;\n background:\n linear-gradient(var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n linear-gradient(90deg, var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default); border-radius: 10px;\n min-height: 620px; overflow: hidden;\n}\n.ps-node {\n position: absolute; width: 190px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong); border-left-width: 3px; border-radius: 8px;\n cursor: pointer;\n}\n.ps-node .nh {\n display: flex; align-items: center; gap: 8px; padding: 9px 11px;\n border-bottom: 1px solid var(--mj-border-subtle); font-weight: 650; font-size: 12.5px; color: var(--mj-text-primary);\n}\n.ps-node .nh i.tile {\n width: 24px; height: 24px; border-radius: 6px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 12px; flex: 0 0 auto;\n}\n.ps-node .nh .ps-tag { margin-left: auto; }\n.ps-node .nb { padding: 9px 11px; font-size: 12px; color: var(--mj-text-secondary); }\n.ps-node .nb-row { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; }\n.ps-node .nb-row .k { color: var(--mj-text-muted); }\n.ps-node.src { border-left-color: var(--ps-node-source); }\n.ps-node.src .nh i.tile { background: var(--ps-node-source); }\n.ps-node.feat { border-left-color: var(--ps-node-feature); }\n.ps-node.feat .nh i.tile { background: var(--ps-node-feature); }\n.ps-node.emb { border-left-color: var(--ps-node-embedding); }\n.ps-node.emb .nh i.tile { background: var(--ps-node-embedding); }\n.ps-node.target { border-left-color: var(--ps-node-target); }\n.ps-node.target .nh i.tile { background: var(--ps-node-target); }\n.ps-node.algo { border-left-color: var(--ps-node-algorithm); }\n.ps-node.algo .nh i.tile { background: var(--ps-node-algorithm); }\n.ps-node.output { border-left-color: var(--mj-status-success); }\n.ps-node.output .nh i.tile { background: var(--mj-status-success); }\n.ps-node.selected {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n.ps-node .port {\n position: absolute; width: 11px; height: 11px; border-radius: 50%;\n background: var(--mj-bg-surface); border: 2px solid var(--mj-brand-primary);\n top: 50%; transform: translateY(-50%);\n}\n.ps-node .port.in { left: -6px; }\n.ps-node .port.out { right: -6px; }\nsvg.ps-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }\nsvg.ps-edges path { stroke: color-mix(in srgb, var(--mj-brand-primary) 45%, transparent); stroke-width: 2; fill: none; }\n\n/* palette chips */\n.ps-pchip {\n display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border-radius: 8px;\n border: 1px dashed var(--mj-border-strong); background: var(--mj-bg-surface);\n font-size: 12.5px; font-weight: 600; color: var(--mj-text-secondary); cursor: grab;\n}\n.ps-pchip i { font-size: 12px; color: var(--mj-text-inverse); width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center; }\n.ps-pchip.s i { background: var(--ps-node-source); }\n.ps-pchip.f i { background: var(--ps-node-feature); }\n.ps-pchip.e i { background: var(--ps-node-embedding); }\n.ps-pchip.t i { background: var(--ps-node-target); }\n.ps-pchip.a i { background: var(--ps-node-algorithm); }\n\n/* segmented control */\n.ps-seg { display: inline-flex; border: 1px solid var(--mj-border-default); border-radius: 8px; overflow: hidden; }\n.ps-seg button {\n border: none; background: var(--mj-bg-surface); color: var(--mj-text-secondary);\n padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer;\n border-right: 1px solid var(--mj-border-default);\n}\n.ps-seg button:last-child { border-right: none; }\n.ps-seg button.on { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n\n/* field control */\n.ps-field { margin-bottom: 14px; }\n.ps-field > label {\n display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; margin-bottom: 6px;\n}\n.ps-input {\n width: 100%; padding: 8px 10px; border: 1px solid var(--mj-border-default);\n border-radius: 6px; font-size: 13px; background: var(--mj-bg-surface); color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n.ps-input:focus { outline: none; border-color: var(--mj-brand-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); }\n\n/* loading container */\n.ps-loading { display: flex; align-items: center; justify-content: center; padding: 60px 0; }\n\n/* ---- empty / prompt states ---- */\n.ps-empty {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n text-align: center; gap: 10px; padding: 56px 24px; color: var(--mj-text-muted);\n}\n.ps-empty .ps-empty-ico {\n width: 60px; height: 60px; border-radius: 16px; display: grid; place-items: center;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-disabled); font-size: 24px;\n}\n.ps-empty h3 { margin: 4px 0 0; font-size: 16px; font-weight: 650; color: var(--mj-text-secondary); }\n.ps-empty p { margin: 0; max-width: 420px; font-size: 13px; line-height: 1.5; }\n\n/* ---- confirm modal ---- */\n.ps-modal-backdrop {\n position: fixed; inset: 0; z-index: 1000;\n background: var(--mj-bg-overlay);\n display: flex; align-items: center; justify-content: center; padding: 24px;\n}\n.ps-modal {\n width: 100%; max-width: 480px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default); border-radius: 14px;\n box-shadow: var(--mj-shadow-lg, var(--mj-shadow-sm)); overflow: hidden;\n}\n.ps-modal-head {\n display: flex; align-items: center; gap: 12px; padding: 18px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-modal-head .ico {\n width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;\n font-size: 16px; flex: 0 0 auto;\n background: var(--mj-status-info-bg); color: var(--mj-status-info-text);\n}\n.ps-modal-head.warn .ico { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-modal-head.danger .ico { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-modal-head h3 { margin: 0; font-size: 15.5px; font-weight: 650; color: var(--mj-text-primary); }\n.ps-modal-body { padding: 18px 20px; font-size: 13.5px; line-height: 1.55; color: var(--mj-text-secondary); }\n.ps-modal-body .ps-field { margin-top: 14px; margin-bottom: 0; }\n.ps-modal-foot {\n display: flex; align-items: center; gap: 10px; padding: 14px 20px;\n border-top: 1px solid var(--mj-border-subtle); background: var(--mj-bg-surface-card);\n}\n.ps-modal-foot .ps-spacer { flex: 1; }\n", "/* Models in Production \u2014 model-centric control tower (master/detail). All colors via --mj-* tokens. */\n\n.ps-production {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n width: 100%;\n overflow: hidden;\n gap: 16px;\n padding: 4px;\n}\n\n.prod-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 14px;\n flex: 0 0 auto;\n}\n\n.prod-layout {\n display: flex;\n flex-direction: row;\n flex: 1;\n min-height: 0;\n height: 100%;\n overflow: hidden;\n position: relative;\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n.prod-splitter {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-page);\n}\n\n.prod-collapsed-strip {\n width: 44px;\n flex: 0 0 44px;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n z-index: 10;\n}\n\n.prod-rail-collapse {\n background: transparent;\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n border-radius: var(--mj-radius-sm);\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.prod-rail-collapse:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.prod-collapsed-strip-label {\n color: var(--mj-text-muted);\n font-size: 16px;\n margin-top: 8px;\n}\n\n.prod-collapse-btn {\n background: transparent;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n border-radius: var(--mj-radius-sm);\n width: 26px;\n height: 26px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.prod-collapse-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n/* master list \u2014 own scroll column */\n.prod-layout .mlist {\n min-height: 0;\n overflow-y: auto;\n align-self: stretch;\n height: 100%;\n border-radius: 0;\n border: none;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.prod-layout .mlist .mrow {\n display: flex;\n align-items: center;\n gap: 11px;\n padding: 10px 10px;\n border-radius: 9px;\n cursor: pointer;\n}\n.prod-layout .mlist .mrow:hover { background: var(--mj-bg-surface-hover); }\n.prod-layout .mlist .mrow.sel { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n.prod-layout .mlist .mrow .ico {\n width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 13px; flex: 0 0 auto;\n}\n.prod-layout .mlist .mrow .nm { font-weight: 640; font-size: 14px; color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.prod-layout .mlist .mrow .ln2 { margin-top: 2px; }\n.prod-layout .mlist .mrow .meta { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex: 0 0 auto; }\n\n/* deploy-state icon colors (master + detail) */\n.st-bound { background: var(--mj-status-success); }\n.st-scheduled { background: var(--mj-status-info); }\n.st-idle { background: var(--mj-text-disabled); }\n\n/* detail \u2014 own scroll column */\n.prod-layout .detail {\n min-height: 0;\n overflow-y: auto;\n align-self: stretch;\n height: 100%;\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.prod-layout .detail .dh { display: flex; align-items: center; gap: 13px; }\n.prod-layout .detail .dh h2 { margin: 0; font-size: 17px; font-weight: 680; color: var(--mj-text-primary); }\n.prod-layout .detail .dh .sub { margin-top: 3px; }\n.prod-layout .detail .big-ico {\n width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 16px; flex: 0 0 auto;\n}\n\n/* binding rows */\n.bind-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--mj-border-subtle); }\n.bind-row:last-child { border-bottom: none; }\n\n/* run history table */\n.runs-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.runs-table th {\n text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default);\n}\n.runs-table td { padding: 7px 8px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-secondary); }\n.runs-table tr:last-child td { border-bottom: none; }\n.runs-table tr.run-row { cursor: pointer; }\n.runs-table tr.run-row:hover td { background: var(--mj-bg-surface-hover); }\n.runs-table .run-right { text-align: right; white-space: nowrap; }\n.runs-table .run-right i { margin-left: 8px; opacity: .5; }\n\n.run-back {\n display: inline-flex; align-items: center; gap: 6px; cursor: pointer;\n background: none; border: none; color: var(--mj-text-link); font-size: 13px; padding: 0 0 10px;\n}\n\n/* collapsible cards and focus mode */\n.prod-header-card.collapsed {\n padding: 0;\n overflow: visible;\n}\n\n.dh-compact {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 14px;\n min-height: 40px;\n box-sizing: border-box;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.dh-compact:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.dh-compact .mini-ico {\n width: 24px;\n height: 24px;\n border-radius: 6px;\n display: grid;\n place-items: center;\n color: var(--mj-text-inverse);\n font-size: 11px;\n flex: 0 0 auto;\n}\n\n.dh-compact .compact-info {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n line-height: 1.4;\n}\n\n.dh-compact .compact-info strong {\n color: var(--mj-text-primary);\n font-size: 13px;\n font-weight: 600;\n}\n\n.prod-deployment-card.collapsed {\n background: var(--mj-bg-surface-card);\n}\n\n.prod-deployment-card.collapsed .ps-card-head {\n min-height: 40px;\n padding: 6px 14px;\n box-sizing: border-box;\n}\n\n.prod-deployment-card .ps-card-head.clickable {\n cursor: pointer;\n user-select: none;\n transition: background-color 0.15s ease;\n}\n\n.prod-deployment-card .ps-card-head.clickable:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.prod-layout .detail.focused-run {\n gap: 8px;\n}\n\n.run-card.focus-fill {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.run-card.focus-fill .run-card-body {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.ps-card-collapse-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: var(--mj-radius-sm, 6px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.15s ease;\n padding: 0;\n flex: 0 0 auto;\n}\n\n.ps-card-collapse-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n.ps-focus-toggle-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: var(--mj-radius-sm, 6px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.ps-focus-toggle-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n.ps-focus-toggle-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.run-drill-nav {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n}\n\n/* empty state CTA spacing (shared .ps-empty) */\n.ps-production .ps-empty p { max-width: 520px; }\n\n"] }]
|
|
828
1109
|
}], null, { engine: [{
|
|
829
1110
|
type: Input
|
|
830
1111
|
}] }); })();
|
|
831
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PSProductionComponent, { className: "PSProductionComponent", filePath: "src/PredictiveStudio/components/ps-production.component.ts", lineNumber:
|
|
1112
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PSProductionComponent, { className: "PSProductionComponent", filePath: "src/PredictiveStudio/components/ps-production.component.ts", lineNumber: 304 }); })();
|
|
832
1113
|
//# sourceMappingURL=ps-production.component.js.map
|