@memberjunction/ng-dashboards 5.46.0 → 5.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +15 -4
  2. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  3. package/dist/DataExplorer/data-explorer-dashboard.component.js +45 -35
  4. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  5. package/dist/DataExplorer/models/explorer-state.interface.d.ts +7 -0
  6. package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
  7. package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
  8. package/dist/Lists/components/lists-browse-resource.component.d.ts +4 -0
  9. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  10. package/dist/Lists/components/lists-browse-resource.component.js +39 -30
  11. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  12. package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
  13. package/dist/Lists/components/lists-my-lists-resource.component.js +14 -12
  14. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  15. package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
  16. package/dist/Lists/components/lists-operations-resource.component.js +6 -1
  17. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  18. package/dist/Lists/services/list-set-operations.service.d.ts +11 -0
  19. package/dist/Lists/services/list-set-operations.service.d.ts.map +1 -1
  20. package/dist/Lists/services/list-set-operations.service.js +27 -2
  21. package/dist/Lists/services/list-set-operations.service.js.map +1 -1
  22. package/dist/PredictiveStudio/at-risk.view-models.d.ts +33 -0
  23. package/dist/PredictiveStudio/at-risk.view-models.d.ts.map +1 -1
  24. package/dist/PredictiveStudio/at-risk.view-models.js +69 -2
  25. package/dist/PredictiveStudio/at-risk.view-models.js.map +1 -1
  26. package/dist/PredictiveStudio/components/ps-catalog.component.js +2 -2
  27. package/dist/PredictiveStudio/components/ps-catalog.component.js.map +1 -1
  28. package/dist/PredictiveStudio/components/ps-compare.component.js +2 -2
  29. package/dist/PredictiveStudio/components/ps-compare.component.js.map +1 -1
  30. package/dist/PredictiveStudio/components/ps-confirm-modal.component.js +2 -2
  31. package/dist/PredictiveStudio/components/ps-confirm-modal.component.js.map +1 -1
  32. package/dist/PredictiveStudio/components/ps-experiments.component.js +2 -2
  33. package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
  34. package/dist/PredictiveStudio/components/ps-home.component.js +2 -2
  35. package/dist/PredictiveStudio/components/ps-home.component.js.map +1 -1
  36. package/dist/PredictiveStudio/components/ps-operate-dialog.component.js +2 -2
  37. package/dist/PredictiveStudio/components/ps-operate-dialog.component.js.map +1 -1
  38. package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts.map +1 -1
  39. package/dist/PredictiveStudio/components/ps-pipelines.component.js +306 -297
  40. package/dist/PredictiveStudio/components/ps-pipelines.component.js.map +1 -1
  41. package/dist/PredictiveStudio/components/ps-production.component.js +2 -2
  42. package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
  43. package/dist/PredictiveStudio/components/ps-registry.component.d.ts +1 -1
  44. package/dist/PredictiveStudio/components/ps-registry.component.d.ts.map +1 -1
  45. package/dist/PredictiveStudio/components/ps-registry.component.js +15 -9
  46. package/dist/PredictiveStudio/components/ps-registry.component.js.map +1 -1
  47. package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts +115 -0
  48. package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts.map +1 -0
  49. package/dist/PredictiveStudio/predictive-studio-agent-context.js +119 -0
  50. package/dist/PredictiveStudio/predictive-studio-agent-context.js.map +1 -0
  51. package/dist/PredictiveStudio/predictive-studio-copilot.view-models.d.ts +36 -0
  52. package/dist/PredictiveStudio/predictive-studio-copilot.view-models.d.ts.map +1 -0
  53. package/dist/PredictiveStudio/predictive-studio-copilot.view-models.js +52 -0
  54. package/dist/PredictiveStudio/predictive-studio-copilot.view-models.js.map +1 -0
  55. package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts +9 -1
  56. package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts.map +1 -1
  57. package/dist/PredictiveStudio/resources/ps-models-resource.component.js +133 -56
  58. package/dist/PredictiveStudio/resources/ps-models-resource.component.js.map +1 -1
  59. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts +50 -1
  60. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
  61. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +591 -165
  62. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
  63. package/dist/PredictiveStudio/resources/ps-resource-base.d.ts +17 -0
  64. package/dist/PredictiveStudio/resources/ps-resource-base.d.ts.map +1 -1
  65. package/dist/PredictiveStudio/resources/ps-resource-base.js +27 -1
  66. package/dist/PredictiveStudio/resources/ps-resource-base.js.map +1 -1
  67. package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts +11 -1
  68. package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts.map +1 -1
  69. package/dist/PredictiveStudio/resources/ps-studio-resource.component.js +199 -99
  70. package/dist/PredictiveStudio/resources/ps-studio-resource.component.js.map +1 -1
  71. package/package.json +59 -59
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';
8
- import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
8
+ import { NormalizeUUID, RegisterClass, UUIDsEqual } from '@memberjunction/global';
9
9
  import { LogError, RunView } from '@memberjunction/core';
10
10
  import { MJEnvironmentEntityExtended } from '@memberjunction/core-entities';
11
11
  import { AIEngineBase } from '@memberjunction/ai-engine-base';
@@ -13,163 +13,262 @@ import { trustDots, trustEvidenceLine } from '@memberjunction/predictive-studio-
13
13
  import { BaseResourceComponent } from '@memberjunction/ng-shared';
14
14
  import { PSResourceBase } from './ps-resource-base';
15
15
  import { buildBusinessCatalog } from '../business-predictions.view-models';
16
- import { parseAtRiskRows, topGlobalDrivers } from '../at-risk.view-models';
16
+ import { parseAtRiskRows, topGlobalDrivers, labelFromRecord } from '../at-risk.view-models';
17
+ import { buildPredictionsAgentContext, resolvePSRecord, buildPSNotFoundError } from '../predictive-studio-agent-context';
18
+ import { validateStringParam } from '../../shared/agent-tool-validation';
19
+ import { buildImprovePrompt, PS_CAPABILITY_CARDS } from '../predictive-studio-copilot.view-models';
17
20
  import * as i0 from "@angular/core";
18
21
  import * as i1 from "@memberjunction/ng-ui-components";
19
22
  import * as i2 from "@memberjunction/ng-shared-generic";
20
23
  import * as i3 from "@memberjunction/ng-conversations";
21
24
  const _c0 = () => [1, 2, 3, 4, 5];
22
- const _forTrack0 = ($index, $item) => $item.modelId;
23
- const _forTrack1 = ($index, $item) => $item.recordId;
25
+ const _forTrack0 = ($index, $item) => $item.title;
26
+ const _forTrack1 = ($index, $item) => $item.modelId;
27
+ const _forTrack2 = ($index, $item) => $item.recordId;
28
+ const _forTrack3 = ($index, $item) => $item.label;
24
29
  function PSPredictionsResourceComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
25
30
  const _r1 = i0.ɵɵgetCurrentView();
26
- i0.ɵɵelementStart(0, "button", 6);
31
+ i0.ɵɵelementStart(0, "button", 8);
27
32
  i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.newPrediction()); });
28
- i0.ɵɵelement(1, "i", 7);
33
+ i0.ɵɵelement(1, "i", 9);
29
34
  i0.ɵɵtext(2, " New prediction ");
30
35
  i0.ɵɵelementEnd();
31
36
  } }
32
37
  function PSPredictionsResourceComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
33
- i0.ɵɵelement(0, "mj-loading", 4);
38
+ i0.ɵɵelement(0, "mj-loading", 5);
34
39
  } }
35
- function PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
40
+ function PSPredictionsResourceComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
36
41
  const _r3 = i0.ɵɵgetCurrentView();
37
- i0.ɵɵelementStart(0, "div", 11);
38
- i0.ɵɵelement(1, "i", 13);
39
- i0.ɵɵelementStart(2, "h3");
40
- i0.ɵɵtext(3, "No predictions yet");
41
- i0.ɵɵelementEnd();
42
- i0.ɵɵelementStart(4, "p", 14);
43
- i0.ɵɵtext(5, "Ask the Model Dev Agent to build your first one.");
44
- i0.ɵɵelementEnd();
45
- i0.ɵɵelementStart(6, "button", 15);
46
- i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.newPrediction()); });
47
- i0.ɵɵelement(7, "i", 7);
48
- i0.ɵɵtext(8, " New prediction");
42
+ i0.ɵɵelementStart(0, "div", 6);
43
+ i0.ɵɵelement(1, "i", 10);
44
+ i0.ɵɵelementStart(2, "div", 11)(3, "strong");
45
+ i0.ɵɵtext(4);
46
+ i0.ɵɵelementEnd();
47
+ i0.ɵɵelementStart(5, "span", 12);
48
+ i0.ɵɵtext(6);
49
49
  i0.ɵɵelementEnd()();
50
+ i0.ɵɵelementStart(7, "button", 13);
51
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_5_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.retryLoad()); });
52
+ i0.ɵɵelement(8, "i", 14);
53
+ i0.ɵɵtext(9, " Try again");
54
+ i0.ɵɵelementEnd()();
55
+ } if (rf & 2) {
56
+ const ctx_r1 = i0.ɵɵnextContext();
57
+ i0.ɵɵadvance(4);
58
+ i0.ɵɵtextInterpolate1("Couldn't load ", ctx_r1.sectionTitle);
59
+ i0.ɵɵadvance(2);
60
+ i0.ɵɵtextInterpolate(ctx_r1.loadError);
61
+ } }
62
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_0_For_9_Template(rf, ctx) { if (rf & 1) {
63
+ i0.ɵɵelementStart(0, "div", 23);
64
+ i0.ɵɵelement(1, "i");
65
+ i0.ɵɵelementStart(2, "div", 25);
66
+ i0.ɵɵtext(3);
67
+ i0.ɵɵelementEnd();
68
+ i0.ɵɵelementStart(4, "div", 26);
69
+ i0.ɵɵtext(5);
70
+ i0.ɵɵelementEnd()();
71
+ } if (rf & 2) {
72
+ const cap_r5 = ctx.$implicit;
73
+ i0.ɵɵadvance();
74
+ i0.ɵɵclassMap(cap_r5.icon);
75
+ i0.ɵɵadvance(2);
76
+ i0.ɵɵtextInterpolate(cap_r5.title);
77
+ i0.ɵɵadvance(2);
78
+ i0.ɵɵtextInterpolate(cap_r5.blurb);
50
79
  } }
51
- function PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_1_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
80
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
52
81
  const _r4 = i0.ɵɵgetCurrentView();
53
- i0.ɵɵelementStart(0, "button", 26);
54
- i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_1_For_2_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const c_r5 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.open(c_r5)); });
82
+ i0.ɵɵelementStart(0, "div", 18)(1, "div", 20);
83
+ i0.ɵɵelement(2, "i", 21);
84
+ i0.ɵɵelementStart(3, "h2");
85
+ i0.ɵɵtext(4, "Predict what's next for your data");
86
+ i0.ɵɵelementEnd();
87
+ i0.ɵɵelementStart(5, "p");
88
+ i0.ɵɵtext(6, "Predictive Studio turns your records into plain-language predictions \u2014 describe what you want to know, and the agent builds and trains a model with you. Here's what you can do:");
89
+ i0.ɵɵelementEnd()();
90
+ i0.ɵɵelementStart(7, "div", 22);
91
+ i0.ɵɵrepeaterCreate(8, PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_0_For_9_Template, 6, 4, "div", 23, _forTrack0);
92
+ i0.ɵɵelementEnd();
93
+ i0.ɵɵelementStart(10, "button", 24);
94
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_0_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.newPrediction()); });
95
+ i0.ɵɵelement(11, "i", 9);
96
+ i0.ɵɵtext(12, " Build your first prediction");
97
+ i0.ɵɵelementEnd()();
98
+ } if (rf & 2) {
99
+ const ctx_r1 = i0.ɵɵnextContext(3);
100
+ i0.ɵɵadvance(8);
101
+ i0.ɵɵrepeater(ctx_r1.capabilityCards);
102
+ } }
103
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
104
+ const _r6 = i0.ɵɵgetCurrentView();
105
+ i0.ɵɵelementStart(0, "button", 37);
106
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_For_2_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const c_r7 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.open(c_r7)); });
55
107
  i0.ɵɵtext(1, "Open ");
56
- i0.ɵɵelement(2, "i", 27);
108
+ i0.ɵɵelement(2, "i", 38);
57
109
  i0.ɵɵelementEnd();
58
110
  } }
59
- function PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_1_For_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
60
- i0.ɵɵelementStart(0, "button", 25);
61
- i0.ɵɵelement(1, "i", 28);
62
- i0.ɵɵtext(2, " Needs an analyst");
111
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_For_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
112
+ const _r8 = i0.ɵɵgetCurrentView();
113
+ i0.ɵɵelementStart(0, "button", 39);
114
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_For_2_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const c_r7 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.improvePrediction(c_r7)); });
115
+ i0.ɵɵelement(1, "i", 21);
116
+ i0.ɵɵtext(2, " Improve this");
63
117
  i0.ɵɵelementEnd();
64
- } if (rf & 2) {
65
- i0.ɵɵproperty("disabled", true);
66
118
  } }
67
- function PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
68
- i0.ɵɵelementStart(0, "div", 17)(1, "div", 18)(2, "span", 19);
69
- i0.ɵɵelement(3, "i", 20);
119
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
120
+ i0.ɵɵelementStart(0, "div", 28)(1, "div", 29)(2, "span", 30);
121
+ i0.ɵɵelement(3, "i", 31);
70
122
  i0.ɵɵtext(4);
71
123
  i0.ɵɵelementEnd()();
72
- i0.ɵɵelementStart(5, "h3", 21);
124
+ i0.ɵɵelementStart(5, "h3", 32);
73
125
  i0.ɵɵtext(6);
74
126
  i0.ɵɵelementEnd();
75
- i0.ɵɵelementStart(7, "p", 22);
127
+ i0.ɵɵelementStart(7, "p", 33);
76
128
  i0.ɵɵtext(8);
77
129
  i0.ɵɵelementEnd();
78
- i0.ɵɵelementStart(9, "div", 23);
79
- i0.ɵɵconditionalCreate(10, PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_1_For_2_Conditional_10_Template, 3, 0, "button", 24)(11, PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_1_For_2_Conditional_11_Template, 3, 1, "button", 25);
130
+ i0.ɵɵelementStart(9, "div", 34);
131
+ i0.ɵɵconditionalCreate(10, PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_For_2_Conditional_10_Template, 3, 0, "button", 35)(11, PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_For_2_Conditional_11_Template, 3, 0, "button", 36);
80
132
  i0.ɵɵelementEnd()();
81
133
  } if (rf & 2) {
82
- const c_r5 = ctx.$implicit;
83
- i0.ɵɵclassProp("blocked", !c_r5.canOpen);
134
+ const c_r7 = ctx.$implicit;
135
+ i0.ɵɵclassProp("blocked", !c_r7.canOpen);
84
136
  i0.ɵɵadvance(2);
85
- i0.ɵɵclassMap("trust-" + c_r5.trust.grade.toLowerCase());
137
+ i0.ɵɵclassMap("trust-" + c_r7.trust.grade.toLowerCase());
86
138
  i0.ɵɵadvance(2);
87
- i0.ɵɵtextInterpolate1(" ", c_r5.canOpen ? c_r5.trust.grade : "Not ready", " ");
139
+ i0.ɵɵtextInterpolate1(" ", c_r7.canOpen ? c_r7.trust.grade : "Not ready", " ");
88
140
  i0.ɵɵadvance(2);
89
- i0.ɵɵtextInterpolate(c_r5.title);
141
+ i0.ɵɵtextInterpolate(c_r7.title);
90
142
  i0.ɵɵadvance(2);
91
- i0.ɵɵtextInterpolate(c_r5.canOpen ? c_r5.trust.oneLiner : c_r5.blockedReason);
143
+ i0.ɵɵtextInterpolate(c_r7.canOpen ? c_r7.trust.oneLiner : c_r7.blockedReason);
92
144
  i0.ɵɵadvance(2);
93
- i0.ɵɵconditional(c_r5.canOpen ? 10 : 11);
145
+ i0.ɵɵconditional(c_r7.canOpen ? 10 : 11);
94
146
  } }
95
- function PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
96
- i0.ɵɵelementStart(0, "div", 12);
97
- i0.ɵɵrepeaterCreate(1, PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_1_For_2_Template, 12, 8, "div", 16, _forTrack0);
147
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
148
+ i0.ɵɵelementStart(0, "div", 19);
149
+ i0.ɵɵrepeaterCreate(1, PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_For_2_Template, 12, 8, "div", 27, _forTrack1);
98
150
  i0.ɵɵelementEnd();
99
151
  } if (rf & 2) {
100
152
  const ctx_r1 = i0.ɵɵnextContext(3);
101
153
  i0.ɵɵadvance();
102
154
  i0.ɵɵrepeater(ctx_r1.cards);
103
155
  } }
104
- function PSPredictionsResourceComponent_Conditional_5_Conditional_2_Template(rf, ctx) { if (rf & 1) {
105
- i0.ɵɵconditionalCreate(0, PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_0_Template, 9, 0, "div", 11)(1, PSPredictionsResourceComponent_Conditional_5_Conditional_2_Conditional_1_Template, 3, 0, "div", 12);
156
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_2_Template(rf, ctx) { if (rf & 1) {
157
+ i0.ɵɵconditionalCreate(0, PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_0_Template, 13, 0, "div", 18)(1, PSPredictionsResourceComponent_Conditional_6_Conditional_2_Conditional_1_Template, 3, 0, "div", 19);
106
158
  } if (rf & 2) {
107
159
  const ctx_r1 = i0.ɵɵnextContext(2);
108
160
  i0.ɵɵconditional(ctx_r1.cards.length === 0 ? 0 : 1);
109
161
  } }
110
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_For_9_Template(rf, ctx) { if (rf & 1) {
111
- i0.ɵɵelement(0, "i", 43);
162
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_For_9_Template(rf, ctx) { if (rf & 1) {
163
+ i0.ɵɵelement(0, "i", 55);
112
164
  } if (rf & 2) {
113
- const d_r7 = ctx.$implicit;
165
+ const d_r10 = ctx.$implicit;
114
166
  const ctx_r1 = i0.ɵɵnextContext(3);
115
- i0.ɵɵclassProp("on", d_r7 <= ctx_r1.dots(ctx_r1.selected));
167
+ i0.ɵɵclassProp("on", d_r10 <= ctx_r1.dots(ctx_r1.selected));
116
168
  } }
117
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_0_For_5_Template(rf, ctx) { if (rf & 1) {
118
- i0.ɵɵelementStart(0, "span", 49);
169
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_0_For_5_Template(rf, ctx) { if (rf & 1) {
170
+ i0.ɵɵelementStart(0, "span", 62);
119
171
  i0.ɵɵtext(1);
120
172
  i0.ɵɵelementEnd();
121
173
  } if (rf & 2) {
122
- const d_r8 = ctx.$implicit;
174
+ const d_r11 = ctx.$implicit;
123
175
  i0.ɵɵadvance();
124
- i0.ɵɵtextInterpolate(d_r8);
176
+ i0.ɵɵtextInterpolate(d_r11);
125
177
  } }
126
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_0_Template(rf, ctx) { if (rf & 1) {
127
- i0.ɵɵelementStart(0, "div", 44);
128
- i0.ɵɵelement(1, "i", 48);
178
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_0_Template(rf, ctx) { if (rf & 1) {
179
+ i0.ɵɵelementStart(0, "div", 56);
180
+ i0.ɵɵelement(1, "i", 61);
129
181
  i0.ɵɵelementStart(2, "strong");
130
182
  i0.ɵɵtext(3, "What's driving this:");
131
183
  i0.ɵɵelementEnd();
132
- i0.ɵɵrepeaterCreate(4, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_0_For_5_Template, 2, 1, "span", 49, i0.ɵɵrepeaterTrackByIdentity);
184
+ i0.ɵɵrepeaterCreate(4, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_0_For_5_Template, 2, 1, "span", 62, i0.ɵɵrepeaterTrackByIdentity);
133
185
  i0.ɵɵelementEnd();
134
186
  } if (rf & 2) {
135
187
  const ctx_r1 = i0.ɵɵnextContext(4);
136
188
  i0.ɵɵadvance(4);
137
189
  i0.ɵɵrepeater(ctx_r1.drivers);
138
190
  } }
139
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_1_Template(rf, ctx) { if (rf & 1) {
140
- i0.ɵɵelement(0, "mj-loading", 45);
191
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_1_Template(rf, ctx) { if (rf & 1) {
192
+ i0.ɵɵelement(0, "mj-loading", 57);
141
193
  } }
142
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_2_For_8_Template(rf, ctx) { if (rf & 1) {
143
- i0.ɵɵelementStart(0, "div", 52)(1, "span", 54);
194
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_2_Template(rf, ctx) { if (rf & 1) {
195
+ const _r12 = i0.ɵɵgetCurrentView();
196
+ i0.ɵɵelementStart(0, "div", 58);
197
+ i0.ɵɵelement(1, "i", 10);
198
+ i0.ɵɵelementStart(2, "span", 63);
199
+ i0.ɵɵtext(3);
200
+ i0.ɵɵelementEnd();
201
+ i0.ɵɵelementStart(4, "button", 13);
202
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_2_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.retryAtRisk()); });
203
+ i0.ɵɵelement(5, "i", 14);
204
+ i0.ɵɵtext(6, " Try again");
205
+ i0.ɵɵelementEnd()();
206
+ } if (rf & 2) {
207
+ const ctx_r1 = i0.ɵɵnextContext(4);
208
+ i0.ɵɵadvance(3);
209
+ i0.ɵɵtextInterpolate1("Couldn't load who's at risk: ", ctx_r1.atRiskError);
210
+ } }
211
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_3_For_8_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
212
+ i0.ɵɵelementStart(0, "span", 75);
213
+ i0.ɵɵelement(1, "i", 76);
144
214
  i0.ɵɵtext(2);
145
215
  i0.ɵɵelementEnd();
146
- i0.ɵɵelementStart(3, "span", 55);
147
- i0.ɵɵelement(4, "span", 56);
216
+ } if (rf & 2) {
217
+ const d_r13 = ctx.$implicit;
218
+ i0.ɵɵclassProp("up", d_r13.up)("down", !d_r13.up);
219
+ i0.ɵɵproperty("title", (d_r13.up ? "Increases risk: " : "Lowers risk: ") + d_r13.label);
220
+ i0.ɵɵadvance();
221
+ i0.ɵɵclassProp("fa-arrow-up", d_r13.up)("fa-arrow-down", !d_r13.up);
222
+ i0.ɵɵadvance();
223
+ i0.ɵɵtextInterpolate1(" ", d_r13.label, " ");
224
+ } }
225
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_3_For_8_Conditional_4_Template(rf, ctx) { if (rf & 1) {
226
+ i0.ɵɵelementStart(0, "span", 70);
227
+ i0.ɵɵrepeaterCreate(1, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_3_For_8_Conditional_4_For_2_Template, 3, 10, "span", 74, _forTrack3);
148
228
  i0.ɵɵelementEnd();
149
- i0.ɵɵelementStart(5, "span", 57);
150
- i0.ɵɵtext(6);
229
+ } if (rf & 2) {
230
+ const r_r14 = i0.ɵɵnextContext().$implicit;
231
+ i0.ɵɵadvance();
232
+ i0.ɵɵrepeater(r_r14.drivers.slice(0, 2));
233
+ } }
234
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_3_For_8_Template(rf, ctx) { if (rf & 1) {
235
+ i0.ɵɵelementStart(0, "div", 66)(1, "div", 68)(2, "span", 69);
236
+ i0.ɵɵtext(3);
237
+ i0.ɵɵelementEnd();
238
+ i0.ɵɵconditionalCreate(4, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_3_For_8_Conditional_4_Template, 3, 0, "span", 70);
239
+ i0.ɵɵelementEnd();
240
+ i0.ɵɵelementStart(5, "span", 71);
241
+ i0.ɵɵelement(6, "span", 72);
242
+ i0.ɵɵelementEnd();
243
+ i0.ɵɵelementStart(7, "span", 73);
244
+ i0.ɵɵtext(8);
151
245
  i0.ɵɵelementEnd()();
152
246
  } if (rf & 2) {
153
- const r_r9 = ctx.$implicit;
247
+ const r_r14 = ctx.$implicit;
154
248
  i0.ɵɵadvance(2);
155
- i0.ɵɵtextInterpolate(r_r9.recordId);
249
+ i0.ɵɵclassProp("mono", !r_r14.label);
250
+ i0.ɵɵproperty("title", r_r14.recordId);
251
+ i0.ɵɵadvance();
252
+ i0.ɵɵtextInterpolate(r_r14.label || r_r14.recordId);
253
+ i0.ɵɵadvance();
254
+ i0.ɵɵconditional(r_r14.drivers && r_r14.drivers.length > 0 ? 4 : -1);
156
255
  i0.ɵɵadvance(2);
157
- i0.ɵɵclassMap("risk-" + r_r9.band);
158
- i0.ɵɵstyleProp("width", r_r9.riskPct, "%");
256
+ i0.ɵɵclassMap("risk-" + r_r14.band);
257
+ i0.ɵɵstyleProp("width", r_r14.riskPct, "%");
159
258
  i0.ɵɵadvance();
160
- i0.ɵɵclassMap("risk-" + r_r9.band);
259
+ i0.ɵɵclassMap("risk-" + r_r14.band);
161
260
  i0.ɵɵadvance();
162
- i0.ɵɵtextInterpolate1("", r_r9.riskPct, "%");
261
+ i0.ɵɵtextInterpolate1("", r_r14.riskPct, "%");
163
262
  } }
164
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_2_Template(rf, ctx) { if (rf & 1) {
165
- i0.ɵɵelementStart(0, "div", 46, 0)(2, "div", 50)(3, "span");
263
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_3_Template(rf, ctx) { if (rf & 1) {
264
+ i0.ɵɵelementStart(0, "div", 59, 0)(2, "div", 64)(3, "span");
166
265
  i0.ɵɵtext(4, "Member");
167
266
  i0.ɵɵelementEnd();
168
- i0.ɵɵelementStart(5, "span", 51);
267
+ i0.ɵɵelementStart(5, "span", 65);
169
268
  i0.ɵɵtext(6, "Likelihood");
170
269
  i0.ɵɵelementEnd()();
171
- i0.ɵɵrepeaterCreate(7, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_2_For_8_Template, 7, 8, "div", 52, _forTrack1);
172
- i0.ɵɵelementStart(9, "div", 53);
270
+ i0.ɵɵrepeaterCreate(7, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_3_For_8_Template, 9, 12, "div", 66, _forTrack2);
271
+ i0.ɵɵelementStart(9, "div", 67);
173
272
  i0.ɵɵtext(10);
174
273
  i0.ɵɵelementEnd()();
175
274
  } if (rf & 2) {
@@ -179,8 +278,8 @@ function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_
179
278
  i0.ɵɵadvance(3);
180
279
  i0.ɵɵtextInterpolate1("", ctx_r1.atRiskRows.length > 50 ? "Showing top 50 of " + ctx_r1.atRiskRows.length : ctx_r1.atRiskRows.length + " members", " \u00B7 highest first");
181
280
  } }
182
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_3_Template(rf, ctx) { if (rf & 1) {
183
- i0.ɵɵelementStart(0, "div", 47);
281
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_4_Template(rf, ctx) { if (rf & 1) {
282
+ i0.ɵɵelementStart(0, "div", 60);
184
283
  i0.ɵɵtext(1, "No results yet \u2014 run this prediction from ");
185
284
  i0.ɵɵelementStart(2, "strong");
186
285
  i0.ɵɵtext(3, "Models in Production");
@@ -188,45 +287,49 @@ function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_
188
287
  i0.ɵɵtext(4, " to see who's at risk.");
189
288
  i0.ɵɵelementEnd();
190
289
  } }
191
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Template(rf, ctx) { if (rf & 1) {
192
- i0.ɵɵconditionalCreate(0, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_0_Template, 6, 0, "div", 44);
193
- i0.ɵɵconditionalCreate(1, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_1_Template, 1, 0, "mj-loading", 45)(2, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_2_Template, 11, 1, "div", 46)(3, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Conditional_3_Template, 5, 0, "div", 47);
290
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Template(rf, ctx) { if (rf & 1) {
291
+ i0.ɵɵconditionalCreate(0, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_0_Template, 6, 0, "div", 56);
292
+ i0.ɵɵconditionalCreate(1, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_1_Template, 1, 0, "mj-loading", 57)(2, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_2_Template, 7, 1, "div", 58)(3, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_3_Template, 11, 1, "div", 59)(4, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Conditional_4_Template, 5, 0, "div", 60);
194
293
  } if (rf & 2) {
195
294
  const ctx_r1 = i0.ɵɵnextContext(3);
196
295
  i0.ɵɵconditional(ctx_r1.drivers.length > 0 ? 0 : -1);
197
296
  i0.ɵɵadvance();
198
- i0.ɵɵconditional(ctx_r1.atRiskLoading ? 1 : ctx_r1.atRiskRows.length > 0 ? 2 : 3);
297
+ i0.ɵɵconditional(ctx_r1.atRiskLoading ? 1 : ctx_r1.atRiskError ? 2 : ctx_r1.atRiskRows.length > 0 ? 3 : 4);
199
298
  } }
200
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_22_Template(rf, ctx) { if (rf & 1) {
201
- const _r10 = i0.ɵɵgetCurrentView();
202
- i0.ɵɵelementStart(0, "button", 58);
203
- i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_22_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.scrollToList()); });
204
- i0.ɵɵelement(1, "i", 59);
299
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_22_Template(rf, ctx) { if (rf & 1) {
300
+ const _r15 = i0.ɵɵgetCurrentView();
301
+ i0.ɵɵelementStart(0, "button", 77);
302
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_22_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.scrollToList()); });
303
+ i0.ɵɵelement(1, "i", 78);
205
304
  i0.ɵɵtext(2, " Review the call list");
206
305
  i0.ɵɵelementEnd();
207
- i0.ɵɵelementStart(3, "button", 60);
208
- i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_22_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.askAgentTo("Save these renewal-risk scores onto the member records so my team can use them.")); });
209
- i0.ɵɵelement(4, "i", 61);
306
+ i0.ɵɵelementStart(3, "button", 79);
307
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_22_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.askAgentTo("Save these renewal-risk scores onto the member records so my team can use them.")); });
308
+ i0.ɵɵelement(4, "i", 80);
210
309
  i0.ɵɵtext(5, " Save scores to records");
211
310
  i0.ɵɵelementEnd();
212
- i0.ɵɵelementStart(6, "button", 62);
213
- i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_22_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.askAgentTo("Put these at-risk members into a list called \"At-Risk Renewals\" for outreach.")); });
214
- i0.ɵɵelement(7, "i", 63);
311
+ i0.ɵɵelementStart(6, "button", 81);
312
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_22_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.sendToList()); });
313
+ i0.ɵɵelement(7, "i", 76);
215
314
  i0.ɵɵtext(8, " Send to a list");
216
315
  i0.ɵɵelementEnd();
217
- i0.ɵɵelementStart(9, "button", 64);
218
- i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_22_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.exportList()); });
219
- i0.ɵɵelement(10, "i", 65);
316
+ i0.ɵɵelementStart(9, "button", 82);
317
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_22_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.exportList()); });
318
+ i0.ɵɵelement(10, "i", 83);
220
319
  i0.ɵɵtext(11, " Share / export");
221
320
  i0.ɵɵelementEnd();
222
321
  } if (rf & 2) {
223
322
  const ctx_r1 = i0.ɵɵnextContext(3);
224
- i0.ɵɵadvance(9);
323
+ i0.ɵɵadvance(6);
324
+ i0.ɵɵproperty("disabled", ctx_r1.creatingList || ctx_r1.atRiskRows.length === 0);
325
+ i0.ɵɵadvance();
326
+ i0.ɵɵclassProp("fa-paper-plane", !ctx_r1.creatingList)("fa-spinner", ctx_r1.creatingList)("fa-spin", ctx_r1.creatingList);
327
+ i0.ɵɵadvance(2);
225
328
  i0.ɵɵproperty("disabled", ctx_r1.atRiskRows.length === 0);
226
329
  } }
227
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_23_Template(rf, ctx) { if (rf & 1) {
228
- i0.ɵɵelementStart(0, "div", 42);
229
- i0.ɵɵelement(1, "i", 28);
330
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_23_Template(rf, ctx) { if (rf & 1) {
331
+ i0.ɵɵelementStart(0, "div", 53);
332
+ i0.ɵɵelement(1, "i", 84);
230
333
  i0.ɵɵtext(2);
231
334
  i0.ɵɵelementEnd();
232
335
  } if (rf & 2) {
@@ -234,36 +337,47 @@ function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_
234
337
  i0.ɵɵadvance(2);
235
338
  i0.ɵɵtextInterpolate1(" ", ctx_r1.selected.trust.gateReason);
236
339
  } }
237
- function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
238
- const _r6 = i0.ɵɵgetCurrentView();
239
- i0.ɵɵelementStart(0, "nav", 29)(1, "a", 30);
240
- i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Template_a_click_1_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.backToCatalog()); });
340
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_24_Template(rf, ctx) { if (rf & 1) {
341
+ i0.ɵɵelementStart(0, "div", 54);
342
+ i0.ɵɵtext(1);
343
+ i0.ɵɵelementEnd();
344
+ } if (rf & 2) {
345
+ const ctx_r1 = i0.ɵɵnextContext(3);
346
+ i0.ɵɵadvance();
347
+ i0.ɵɵtextInterpolate(ctx_r1.listResult);
348
+ } }
349
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Template(rf, ctx) { if (rf & 1) {
350
+ const _r9 = i0.ɵɵgetCurrentView();
351
+ i0.ɵɵelementStart(0, "nav", 40)(1, "a", 41);
352
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_3_Template_a_click_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.backToCatalog()); });
241
353
  i0.ɵɵtext(2, "Predictions");
242
354
  i0.ɵɵelementEnd();
243
- i0.ɵɵelement(3, "i", 31);
355
+ i0.ɵɵelement(3, "i", 42);
244
356
  i0.ɵɵelementStart(4, "span");
245
357
  i0.ɵɵtext(5);
246
358
  i0.ɵɵelementEnd()();
247
- i0.ɵɵelementStart(6, "div", 32)(7, "div", 33);
248
- i0.ɵɵrepeaterCreate(8, PSPredictionsResourceComponent_Conditional_5_Conditional_3_For_9_Template, 1, 2, "i", 34, i0.ɵɵrepeaterTrackByIdentity);
359
+ i0.ɵɵelementStart(6, "div", 43)(7, "div", 44);
360
+ i0.ɵɵrepeaterCreate(8, PSPredictionsResourceComponent_Conditional_6_Conditional_3_For_9_Template, 1, 2, "i", 45, i0.ɵɵrepeaterTrackByIdentity);
249
361
  i0.ɵɵelementEnd();
250
- i0.ɵɵelementStart(10, "div", 35)(11, "div", 36);
362
+ i0.ɵɵelementStart(10, "div", 46)(11, "div", 47);
251
363
  i0.ɵɵtext(12);
252
364
  i0.ɵɵelementEnd();
253
- i0.ɵɵelementStart(13, "div", 37);
365
+ i0.ɵɵelementStart(13, "div", 48);
254
366
  i0.ɵɵtext(14);
255
367
  i0.ɵɵelementEnd();
256
- i0.ɵɵelementStart(15, "div", 38);
368
+ i0.ɵɵelementStart(15, "div", 49);
257
369
  i0.ɵɵtext(16);
258
370
  i0.ɵɵelementEnd();
259
- i0.ɵɵelementStart(17, "div", 39);
371
+ i0.ɵɵelementStart(17, "div", 50);
260
372
  i0.ɵɵtext(18);
261
373
  i0.ɵɵelementEnd()()();
262
- i0.ɵɵelementStart(19, "div", 40);
263
- i0.ɵɵconditionalCreate(20, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_20_Template, 4, 2);
264
- i0.ɵɵelementStart(21, "div", 41);
265
- i0.ɵɵconditionalCreate(22, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_22_Template, 12, 1)(23, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Conditional_23_Template, 3, 1, "div", 42);
266
- i0.ɵɵelementEnd()();
374
+ i0.ɵɵelementStart(19, "div", 51);
375
+ i0.ɵɵconditionalCreate(20, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_20_Template, 5, 2);
376
+ i0.ɵɵelementStart(21, "div", 52);
377
+ i0.ɵɵconditionalCreate(22, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_22_Template, 12, 8)(23, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_23_Template, 3, 1, "div", 53);
378
+ i0.ɵɵelementEnd();
379
+ i0.ɵɵconditionalCreate(24, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Conditional_24_Template, 2, 1, "div", 54);
380
+ i0.ɵɵelementEnd();
267
381
  } if (rf & 2) {
268
382
  const ctx_r1 = i0.ɵɵnextContext(2);
269
383
  i0.ɵɵadvance(5);
@@ -271,7 +385,7 @@ function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Template(rf,
271
385
  i0.ɵɵadvance();
272
386
  i0.ɵɵclassMap("trust-" + ctx_r1.selected.trust.grade.toLowerCase());
273
387
  i0.ɵɵadvance(2);
274
- i0.ɵɵrepeater(i0.ɵɵpureFunction0(11, _c0));
388
+ i0.ɵɵrepeater(i0.ɵɵpureFunction0(12, _c0));
275
389
  i0.ɵɵadvance(4);
276
390
  i0.ɵɵtextInterpolate(ctx_r1.selected.canOpen ? "You can rely on this \u2014 " + ctx_r1.selected.trust.grade : "Not reliable yet");
277
391
  i0.ɵɵadvance(2);
@@ -286,45 +400,47 @@ function PSPredictionsResourceComponent_Conditional_5_Conditional_3_Template(rf,
286
400
  i0.ɵɵclassProp("locked", !ctx_r1.selected.canOpen);
287
401
  i0.ɵɵadvance();
288
402
  i0.ɵɵconditional(ctx_r1.selected.canOpen ? 22 : 23);
403
+ i0.ɵɵadvance(2);
404
+ i0.ɵɵconditional(ctx_r1.listResult ? 24 : -1);
289
405
  } }
290
- function PSPredictionsResourceComponent_Conditional_5_Conditional_4_Conditional_8_Template(rf, ctx) { if (rf & 1) {
291
- const _r12 = i0.ɵɵgetCurrentView();
292
- i0.ɵɵelementStart(0, "mj-conversation-chat-area", 74);
293
- i0.ɵɵlistener("conversationCreated", function PSPredictionsResourceComponent_Conditional_5_Conditional_4_Conditional_8_Template_mj_conversation_chat_area_conversationCreated_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onChatConversationCreated($event)); })("pendingMessageConsumed", function PSPredictionsResourceComponent_Conditional_5_Conditional_4_Conditional_8_Template_mj_conversation_chat_area_pendingMessageConsumed_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onChatPendingMessageConsumed()); });
406
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_4_Conditional_8_Template(rf, ctx) { if (rf & 1) {
407
+ const _r17 = i0.ɵɵgetCurrentView();
408
+ i0.ɵɵelementStart(0, "mj-conversation-chat-area", 93);
409
+ i0.ɵɵlistener("conversationCreated", function PSPredictionsResourceComponent_Conditional_6_Conditional_4_Conditional_8_Template_mj_conversation_chat_area_conversationCreated_0_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onChatConversationCreated($event)); })("pendingMessageConsumed", function PSPredictionsResourceComponent_Conditional_6_Conditional_4_Conditional_8_Template_mj_conversation_chat_area_pendingMessageConsumed_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onChatPendingMessageConsumed()); });
294
410
  i0.ɵɵelementEnd();
295
411
  } if (rf & 2) {
296
412
  const ctx_r1 = i0.ɵɵnextContext(3);
297
413
  i0.ɵɵproperty("Provider", ctx_r1.Provider)("environmentId", ctx_r1.chatEnvironmentId)("currentUser", ctx_r1.currentUser)("conversation", ctx_r1.chatConversation)("conversationId", ctx_r1.chatConversationId)("isNewConversation", ctx_r1.chatIsNewConversation)("suppressNewConversationEmptyState", true)("allowMentions", false)("overlayMode", true)("showExportButton", false)("showShareButton", false)("showArtifactIndicator", false)("showAgentPicker", false)("showAgentModePicker", false)("defaultAgentId", ctx_r1.modelDevAgentId)("pendingMessage", ctx_r1.pendingPrompt)("applicationScope", "Application")("applicationId", ctx_r1.applicationId)("appContext", ctx_r1.chatAppContext);
298
414
  } }
299
- function PSPredictionsResourceComponent_Conditional_5_Conditional_4_Conditional_9_Template(rf, ctx) { if (rf & 1) {
300
- i0.ɵɵelementStart(0, "div", 73);
301
- i0.ɵɵelement(1, "mj-loading", 75);
415
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_4_Conditional_9_Template(rf, ctx) { if (rf & 1) {
416
+ i0.ɵɵelementStart(0, "div", 92);
417
+ i0.ɵɵelement(1, "mj-loading", 94);
302
418
  i0.ɵɵelementEnd();
303
419
  } }
304
- function PSPredictionsResourceComponent_Conditional_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
305
- const _r11 = i0.ɵɵgetCurrentView();
306
- i0.ɵɵelementStart(0, "aside", 10)(1, "div", 66)(2, "div", 67);
307
- i0.ɵɵelement(3, "i", 68);
420
+ function PSPredictionsResourceComponent_Conditional_6_Conditional_4_Template(rf, ctx) { if (rf & 1) {
421
+ const _r16 = i0.ɵɵgetCurrentView();
422
+ i0.ɵɵelementStart(0, "aside", 17)(1, "div", 85)(2, "div", 86);
423
+ i0.ɵɵelement(3, "i", 87);
308
424
  i0.ɵɵtext(4, " New prediction");
309
425
  i0.ɵɵelementEnd();
310
- i0.ɵɵelementStart(5, "button", 69);
311
- i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_5_Conditional_4_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.closeChat()); });
312
- i0.ɵɵelement(6, "i", 70);
426
+ i0.ɵɵelementStart(5, "button", 88);
427
+ i0.ɵɵlistener("click", function PSPredictionsResourceComponent_Conditional_6_Conditional_4_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.closeChat()); });
428
+ i0.ɵɵelement(6, "i", 89);
313
429
  i0.ɵɵelementEnd()();
314
- i0.ɵɵelementStart(7, "div", 71);
315
- i0.ɵɵconditionalCreate(8, PSPredictionsResourceComponent_Conditional_5_Conditional_4_Conditional_8_Template, 1, 19, "mj-conversation-chat-area", 72)(9, PSPredictionsResourceComponent_Conditional_5_Conditional_4_Conditional_9_Template, 2, 0, "div", 73);
430
+ i0.ɵɵelementStart(7, "div", 90);
431
+ i0.ɵɵconditionalCreate(8, PSPredictionsResourceComponent_Conditional_6_Conditional_4_Conditional_8_Template, 1, 19, "mj-conversation-chat-area", 91)(9, PSPredictionsResourceComponent_Conditional_6_Conditional_4_Conditional_9_Template, 2, 0, "div", 92);
316
432
  i0.ɵɵelementEnd()();
317
433
  } if (rf & 2) {
318
434
  const ctx_r1 = i0.ɵɵnextContext(2);
319
435
  i0.ɵɵadvance(8);
320
436
  i0.ɵɵconditional(ctx_r1.currentUser ? 8 : 9);
321
437
  } }
322
- function PSPredictionsResourceComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
323
- i0.ɵɵelementStart(0, "div", 8)(1, "div", 9);
324
- i0.ɵɵconditionalCreate(2, PSPredictionsResourceComponent_Conditional_5_Conditional_2_Template, 2, 1);
325
- i0.ɵɵconditionalCreate(3, PSPredictionsResourceComponent_Conditional_5_Conditional_3_Template, 24, 12);
438
+ function PSPredictionsResourceComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
439
+ i0.ɵɵelementStart(0, "div", 15)(1, "div", 16);
440
+ i0.ɵɵconditionalCreate(2, PSPredictionsResourceComponent_Conditional_6_Conditional_2_Template, 2, 1);
441
+ i0.ɵɵconditionalCreate(3, PSPredictionsResourceComponent_Conditional_6_Conditional_3_Template, 25, 13);
326
442
  i0.ɵɵelementEnd();
327
- i0.ɵɵconditionalCreate(4, PSPredictionsResourceComponent_Conditional_5_Conditional_4_Template, 10, 1, "aside", 10);
443
+ i0.ɵɵconditionalCreate(4, PSPredictionsResourceComponent_Conditional_6_Conditional_4_Template, 10, 1, "aside", 17);
328
444
  i0.ɵɵelementEnd();
329
445
  } if (rf & 2) {
330
446
  const ctx_r1 = i0.ɵɵnextContext();
@@ -372,6 +488,13 @@ let PSPredictionsResourceComponent = class PSPredictionsResourceComponent extend
372
488
  drivers = [];
373
489
  /** Whether the at-risk list is loading for the open prediction. */
374
490
  atRiskLoading = false;
491
+ /** Set when the at-risk load fails — the workspace shows a "couldn't load" banner with retry instead of the misleading no-results empty state. */
492
+ atRiskError = null;
493
+ /** "Send to a list" in-flight guard + last-result message (P1 #4). */
494
+ creatingList = false;
495
+ listResult = null;
496
+ /** Capability cards for the first-run intro (what PS can do), shown when the catalog is empty. */
497
+ capabilityCards = PS_CAPABILITY_CARDS;
375
498
  /** The business catalog cards, most-trustworthy first, derived from the engine's published models. */
376
499
  get cards() {
377
500
  return buildBusinessCatalog(this.engine.PublishedModels.map((m) => ({
@@ -385,6 +508,98 @@ let PSPredictionsResourceComponent = class PSPredictionsResourceComponent extend
385
508
  }
386
509
  dots(c) { return trustDots(c.trust.grade); }
387
510
  evidence() { return trustEvidenceLine({ noun: 'members' }); }
511
+ /** Deep agent context for the Predictions door: catalog counts + names, and (in workspace) the selection + at-risk breakdown. */
512
+ extraAgentContext() {
513
+ const cards = this.cards;
514
+ return buildPredictionsAgentContext({
515
+ View: this.view,
516
+ PredictionCount: cards.length,
517
+ ReadyPredictionCount: cards.filter((c) => c.canOpen).length,
518
+ VisiblePredictionNames: cards.map((c) => c.title),
519
+ ChatOpen: this.chatOpen,
520
+ Selected: this.selected ? { Name: this.selected.title, TrustGrade: this.selected.trust.grade, CanOpen: this.selected.canOpen } : null,
521
+ AtRiskLoaded: this.view === 'workspace' && !this.atRiskLoading && !this.atRiskError,
522
+ AtRiskCount: this.atRiskRows.length,
523
+ HighRiskCount: this.atRiskRows.filter((r) => r.band === 'high').length,
524
+ MediumRiskCount: this.atRiskRows.filter((r) => r.band === 'medium').length,
525
+ LowRiskCount: this.atRiskRows.filter((r) => r.band === 'low').length,
526
+ Drivers: this.drivers,
527
+ });
528
+ }
529
+ /**
530
+ * 🔒 Read/navigate-only agent tools for the Predictions door: open a (trust-cleared) prediction, go back
531
+ * to the catalog, review the call list, export the at-risk list (CSV — read-only, mirrors Data Explorer's
532
+ * ExportView), and open the "+ New prediction" co-pilot. **DELIBERATELY NOT exposed:** "Save scores to
533
+ * records", "Send to a list" (both WRITE records), and any train/publish/delete — those stay behind the
534
+ * user's clicks and the approve-gated builder.
535
+ */
536
+ registerAgentTools() {
537
+ this.navigationService.SetAgentClientTools(this, [
538
+ {
539
+ Name: 'OpenPrediction',
540
+ Description: 'Open a prediction to its workspace (trust verdict + who-is-at-risk list). Pass the prediction ID or name (see VisiblePredictionNames). Only trust-cleared predictions can open; a blocked one returns why.',
541
+ ParameterSchema: { type: 'object', properties: { prediction: { type: 'string', description: 'The prediction ID or name to open' } } },
542
+ Handler: async (params) => {
543
+ const check = validateStringParam(params['prediction'], 'prediction');
544
+ if (!check.ok)
545
+ return check.result;
546
+ const candidates = this.cards.map((c) => ({ ID: c.modelId, Name: c.title }));
547
+ const match = resolvePSRecord(check.value, candidates);
548
+ if (!match)
549
+ return { Success: false, ErrorMessage: buildPSNotFoundError(check.value, candidates, 'prediction') };
550
+ const card = this.cards.find((c) => UUIDsEqual(c.modelId, match.ID));
551
+ if (!card)
552
+ return { Success: false, ErrorMessage: buildPSNotFoundError(check.value, candidates, 'prediction') };
553
+ if (!card.canOpen) {
554
+ return { Success: false, ErrorMessage: `"${card.title}" isn't ready to open: ${card.blockedReason ?? card.trust.gateReason ?? 'it needs an analyst first.'}` };
555
+ }
556
+ this.open(card);
557
+ return { Success: true, Data: { opened: card.title, trust: card.trust.grade } };
558
+ },
559
+ },
560
+ {
561
+ Name: 'BackToPredictionCatalog',
562
+ Description: 'Return from a prediction workspace to the catalog (the grid of all predictions).',
563
+ ParameterSchema: { type: 'object', properties: {} },
564
+ Handler: async () => {
565
+ this.backToCatalog();
566
+ this.publishAgentContext();
567
+ return { Success: true, Data: { view: 'catalog' } };
568
+ },
569
+ },
570
+ {
571
+ Name: 'ReviewCallList',
572
+ Description: 'Scroll the open prediction workspace to its ranked at-risk "call list". Only meaningful when a prediction is open.',
573
+ ParameterSchema: { type: 'object', properties: {} },
574
+ Handler: async () => {
575
+ if (this.view !== 'workspace' || !this.selected)
576
+ return { Success: false, ErrorMessage: 'No prediction is open. Use OpenPrediction first.' };
577
+ this.scrollToList();
578
+ return { Success: true };
579
+ },
580
+ },
581
+ {
582
+ Name: 'ExportAtRiskList',
583
+ Description: 'Download the open prediction\'s at-risk list as a CSV (read-only export). Only works when a prediction is open and its list has loaded.',
584
+ ParameterSchema: { type: 'object', properties: {} },
585
+ Handler: async () => {
586
+ if (this.view !== 'workspace' || this.atRiskRows.length === 0)
587
+ return { Success: false, ErrorMessage: 'No at-risk list is loaded to export. Open a prediction with results first.' };
588
+ this.exportList();
589
+ return { Success: true, Data: { rows: this.atRiskRows.length } };
590
+ },
591
+ },
592
+ {
593
+ Name: 'OpenNewPredictionCopilot',
594
+ Description: 'Open the "+ New prediction" Model Development Agent co-pilot (does not send a message — the user drives the conversation). Use when the user wants to build a new prediction.',
595
+ ParameterSchema: { type: 'object', properties: {} },
596
+ Handler: async () => {
597
+ this.openNewPredictionCopilot();
598
+ return { Success: true, Data: { chatOpen: true } };
599
+ },
600
+ },
601
+ ]);
602
+ }
388
603
  open(c) {
389
604
  if (!c.canOpen)
390
605
  return;
@@ -392,6 +607,12 @@ let PSPredictionsResourceComponent = class PSPredictionsResourceComponent extend
392
607
  this.view = 'workspace';
393
608
  this.atRiskRows = [];
394
609
  this.drivers = [];
610
+ this.atRiskError = null;
611
+ this.listResult = null;
612
+ // Mark loading BEFORE the publish below: otherwise AtRiskLoaded computes true for one publish with
613
+ // atRiskRows still [], fabricating "0 at risk" to the agent for a list that hasn't been fetched yet.
614
+ this.atRiskLoading = true;
615
+ this.publishAgentContext();
395
616
  this.cdrLocal.detectChanges();
396
617
  void this.loadAtRisk(c);
397
618
  }
@@ -400,6 +621,7 @@ let PSPredictionsResourceComponent = class PSPredictionsResourceComponent extend
400
621
  const model = this.engine.PublishedModels.find((m) => UUIDsEqual(m.ID, c.modelId));
401
622
  this.drivers = topGlobalDrivers(model?.FeatureImportance ?? null, 3);
402
623
  this.atRiskLoading = true;
624
+ this.atRiskError = null;
403
625
  this.cdrLocal.detectChanges();
404
626
  try {
405
627
  const provider = this.ProviderToUse;
@@ -410,40 +632,178 @@ let PSPredictionsResourceComponent = class PSPredictionsResourceComponent extend
410
632
  const res = await RunView.FromMetadataProvider(provider).RunView({ EntityName: 'MJ: Process Run Details', ExtraFilter: `ProcessRunID='${latest.ID}'`, MaxRows: 2137, ResultType: 'entity_object' }, user);
411
633
  if (res.Success && this.selected?.modelId === c.modelId) {
412
634
  this.atRiskRows = parseAtRiskRows((res.Results ?? []).map((d) => ({ recordId: d.RecordID, ResultPayload: d.ResultPayload })));
635
+ await this.resolveAtRiskLabels(model);
413
636
  }
414
637
  }
415
638
  }
416
639
  catch (err) {
417
- LogError(`PSPredictionsResource.loadAtRisk: ${err instanceof Error ? err.message : String(err)}`);
640
+ this.atRiskError = err instanceof Error ? err.message : String(err);
641
+ LogError(`PSPredictionsResource.loadAtRisk: ${this.atRiskError}`);
418
642
  }
419
643
  finally {
420
644
  this.atRiskLoading = false;
645
+ this.publishAgentContext();
421
646
  this.cdrLocal.detectChanges();
422
647
  }
423
648
  }
649
+ /** Retry loading the open prediction's at-risk list after a failure — bound to the at-risk error banner. */
650
+ retryAtRisk() {
651
+ if (this.selected)
652
+ void this.loadAtRisk(this.selected);
653
+ }
654
+ /**
655
+ * P1 #3 — resolve the raw record ids in the at-risk list to human labels (member name/email) from the
656
+ * model's target entity, so the list reads like a call sheet instead of a column of UUIDs. Resolves the
657
+ * top-risk rows (capped) to keep the lookup light; unresolved rows fall back to their id in the template.
658
+ */
659
+ /** Resolve a model's scored target entity (id + name) via its pipeline — the model row itself only carries PipelineID. */
660
+ targetEntityForModel(model) {
661
+ const pipeline = model ? this.engine.Pipelines.find((pp) => UUIDsEqual(pp.ID, model.PipelineID)) : undefined;
662
+ const id = pipeline?.TargetEntityID;
663
+ if (!id)
664
+ return null;
665
+ const name = this.ProviderToUse.Entities.find((e) => UUIDsEqual(e.ID, id))?.Name;
666
+ return name ? { id, name } : null;
667
+ }
668
+ async resolveAtRiskLabels(model) {
669
+ // Labels are cosmetic — any failure here degrades to record ids, it must never surface as a
670
+ // "couldn't load who's at risk" error that hides a perfectly good list.
671
+ try {
672
+ const target = this.targetEntityForModel(model);
673
+ if (!target || this.atRiskRows.length === 0)
674
+ return;
675
+ const entity = this.ProviderToUse.EntityByName(target.name);
676
+ const targets = this.atRiskRows.slice(0, 200); // the rows a user actually acts on
677
+ const ids = targets.map((r) => `'${r.recordId.replace(/'/g, "''")}'`);
678
+ // Only fetch the columns labelFromRecord can actually use — a broad no-Fields fetch pulls every
679
+ // column (incl. large text/JSON) of an arbitrary entity just to render a display name. Fall back
680
+ // to the broad fetch only when the entity has none of the candidate label fields.
681
+ const candidates = ['Name', 'FirstName', 'LastName', 'Email'];
682
+ const labelFields = entity ? candidates.filter((c) => entity.Fields.some((f) => f.Name.toLowerCase() === c.toLowerCase())) : [];
683
+ const res = await RunView.FromMetadataProvider(this.ProviderToUse).RunView({
684
+ EntityName: target.name,
685
+ ExtraFilter: `ID IN (${ids.join(',')})`,
686
+ ...(labelFields.length > 0 ? { Fields: ['ID', ...labelFields] } : {}),
687
+ ResultType: 'simple',
688
+ MaxRows: ids.length,
689
+ }, this.ProviderToUse.CurrentUser ?? undefined);
690
+ if (!res.Success)
691
+ return;
692
+ const byId = new Map();
693
+ for (const row of res.Results ?? [])
694
+ byId.set(NormalizeUUID(String(row.ID ?? '')), row);
695
+ for (const r of this.atRiskRows) {
696
+ const rec = byId.get(NormalizeUUID(r.recordId));
697
+ if (rec)
698
+ r.label = labelFromRecord(rec);
699
+ }
700
+ }
701
+ catch (err) {
702
+ LogError(`PSPredictionsResource.resolveAtRiskLabels (cosmetic — list keeps ids): ${err instanceof Error ? err.message : String(err)}`);
703
+ }
704
+ }
424
705
  backToCatalog() {
425
706
  this.view = 'catalog';
426
707
  this.selected = null;
427
708
  this.atRiskRows = [];
428
709
  this.drivers = [];
710
+ this.atRiskError = null;
711
+ this.publishAgentContext();
429
712
  this.cdrLocal.detectChanges();
430
713
  }
431
714
  /** "Review the call list" — scroll the ranked at-risk list into view. */
432
715
  scrollToList() {
433
716
  document.querySelector('[data-testid="ps-atrisk-list"]')?.scrollIntoView({ behavior: 'smooth', block: 'start' });
434
717
  }
435
- /** "Save scores" / "Send to a list" — open the docked co-pilot seeded with the request (the agent does it). */
718
+ /** "Save scores" still routed conversationally through the co-pilot (needs a designated write-back column). */
436
719
  askAgentTo(prompt) {
437
720
  this.pendingPrompt = prompt;
438
721
  this.chatOpen = true;
439
722
  void this.ensureModelDevAgentResolved();
440
723
  this.cdrLocal.detectChanges();
441
724
  }
725
+ /**
726
+ * P1 #4 — "Send to a list" as a one-click server action (no agent sentence to parse): create an MJ List
727
+ * over the model's target entity and add the at-risk members (high/medium band, capped) so a team can
728
+ * act on it immediately (outreach campaign, tasks, etc.).
729
+ */
730
+ async sendToList() {
731
+ if (this.creatingList || this.atRiskRows.length === 0 || !this.selected)
732
+ return;
733
+ const model = this.engine.PublishedModels.find((m) => UUIDsEqual(m.ID, this.selected.modelId));
734
+ const target = this.targetEntityForModel(model);
735
+ const entityId = target?.id;
736
+ if (!entityId)
737
+ return;
738
+ this.creatingList = true;
739
+ this.listResult = null;
740
+ this.cdrLocal.detectChanges();
741
+ try {
742
+ const p = this.ProviderToUse;
743
+ const user = p.CurrentUser ?? undefined;
744
+ const list = await p.GetEntityObject('MJ: Lists', user);
745
+ // Minute-resolution timestamp so two sends on the same day don't produce identical-named lists.
746
+ list.Name = `At-Risk: ${this.selected.title} (${new Date().toISOString().slice(0, 16).replace('T', ' ')})`;
747
+ list.EntityID = entityId;
748
+ if (user?.ID)
749
+ list.UserID = user.ID;
750
+ list.RefreshMode = 'Additive';
751
+ list.UseSnapshot = false;
752
+ if (!(await list.Save())) {
753
+ this.listResult = `Couldn't create the list: ${list.LatestResult?.CompleteMessage ?? 'unknown error'}`;
754
+ return;
755
+ }
756
+ const members = this.atRiskRows.filter((r) => r.band !== 'low').slice(0, 200);
757
+ let seq = 0;
758
+ let added = 0;
759
+ let firstFailure = null;
760
+ for (const r of members) {
761
+ const ld = await p.GetEntityObject('MJ: List Details', user);
762
+ ld.ListID = list.ID;
763
+ ld.RecordID = r.recordId;
764
+ ld.Sequence = seq++;
765
+ ld.Status = 'Active';
766
+ if (await ld.Save()) {
767
+ added++;
768
+ }
769
+ else if (!firstFailure) {
770
+ firstFailure = ld.LatestResult?.CompleteMessage ?? 'unknown error';
771
+ }
772
+ }
773
+ const failed = members.length - added;
774
+ this.listResult =
775
+ failed === 0
776
+ ? `Added ${added} at-risk member${added === 1 ? '' : 's'} to “${list.Name}”.`
777
+ : `Added ${added} of ${members.length} members to “${list.Name}” — ${failed} failed to add (first error: ${firstFailure}).`;
778
+ if (failed > 0)
779
+ LogError(`PSPredictionsResource.sendToList: ${failed}/${members.length} adds failed. First: ${firstFailure}`);
780
+ }
781
+ catch (err) {
782
+ this.listResult = `Couldn't create the list: ${err instanceof Error ? err.message : String(err)}`;
783
+ LogError(`PSPredictionsResource.sendToList: ${err instanceof Error ? err.message : String(err)}`);
784
+ }
785
+ finally {
786
+ this.creatingList = false;
787
+ this.cdrLocal.detectChanges();
788
+ }
789
+ }
790
+ /**
791
+ * Quote one CSV cell: RFC-4180 double-quote escaping (handles commas/quotes/newlines in labels) plus a
792
+ * leading `'` on formula-starting characters (`=`, `+`, `-`, `@`) so a hostile label can't execute as an
793
+ * Excel/Sheets formula on open.
794
+ */
795
+ csvCell(value) {
796
+ const guarded = /^[=+\-@]/.test(value) ? `'${value}` : value;
797
+ return /[",\n\r]/.test(guarded) ? `"${guarded.replace(/"/g, '""')}"` : guarded;
798
+ }
442
799
  /** "Share / export" — download the at-risk list as a CSV (dependency-free). */
443
800
  exportList() {
444
801
  if (this.atRiskRows.length === 0)
445
802
  return;
446
- const csv = ['Member,Likelihood %,Predicted', ...this.atRiskRows.map((r) => `${r.recordId},${r.riskPct},${r.class ?? ''}`)].join('\n');
803
+ const csv = [
804
+ 'Member,Likelihood %,Predicted',
805
+ ...this.atRiskRows.map((r) => `${this.csvCell(r.label ?? r.recordId)},${r.riskPct},${this.csvCell(r.class ?? '')}`),
806
+ ].join('\n');
447
807
  const url = URL.createObjectURL(new Blob([csv], { type: 'text/csv' }));
448
808
  const a = document.createElement('a');
449
809
  a.href = url;
@@ -451,15 +811,42 @@ let PSPredictionsResourceComponent = class PSPredictionsResourceComponent extend
451
811
  a.click();
452
812
  URL.revokeObjectURL(url);
453
813
  }
814
+ /** "+ New prediction" — open the co-pilot to a clean chat (Sonar-style); the user describes their goal and the agent drives the build. */
454
815
  newPrediction() {
455
- this.pendingPrompt = 'Help me build a new prediction. What do you want to know about your members?';
816
+ this.pendingPrompt = null;
456
817
  this.chatOpen = true;
457
818
  void this.ensureModelDevAgentResolved();
819
+ this.publishAgentContext();
820
+ this.cdrLocal.detectChanges();
821
+ }
822
+ /**
823
+ * "Improve this" on a blocked (not-trustworthy-enough) prediction — turns the trust dead-end into a next
824
+ * step by opening the co-pilot seeded with the model's name + why it's held, so the agent proposes concrete
825
+ * ways to make it reliable and can rebuild it.
826
+ */
827
+ improvePrediction(c) {
828
+ this.pendingPrompt = buildImprovePrompt({
829
+ name: c.title,
830
+ trustGrade: c.trust.grade,
831
+ reason: c.blockedReason ?? c.trust.gateReason ?? null,
832
+ });
833
+ this.chatOpen = true;
834
+ void this.ensureModelDevAgentResolved();
835
+ this.publishAgentContext();
836
+ this.cdrLocal.detectChanges();
837
+ }
838
+ /** Open the "+ New prediction" co-pilot (clean chat) — used by the read-only `OpenNewPredictionCopilot` agent tool. */
839
+ openNewPredictionCopilot() {
840
+ this.pendingPrompt = null;
841
+ this.chatOpen = true;
842
+ void this.ensureModelDevAgentResolved();
843
+ this.publishAgentContext();
458
844
  this.cdrLocal.detectChanges();
459
845
  }
460
846
  closeChat() {
461
847
  this.chatOpen = false;
462
848
  this.pendingPrompt = null;
849
+ this.publishAgentContext();
463
850
  this.cdrLocal.detectChanges();
464
851
  }
465
852
  /**
@@ -504,20 +891,22 @@ let PSPredictionsResourceComponent = class PSPredictionsResourceComponent extend
504
891
  }
505
892
  }
506
893
  static ɵfac = /*@__PURE__*/ (() => { let ɵPSPredictionsResourceComponent_BaseFactory; return function PSPredictionsResourceComponent_Factory(__ngFactoryType__) { return (ɵPSPredictionsResourceComponent_BaseFactory || (ɵPSPredictionsResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(PSPredictionsResourceComponent)))(__ngFactoryType__ || PSPredictionsResourceComponent); }; })();
507
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PSPredictionsResourceComponent, selectors: [["mj-ps-predictions-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 4, consts: [["atriskList", ""], [3, "Title", "Subtitle"], ["actions", ""], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-new-prediction"], ["text", "Loading your predictions\u2026", "size", "medium"], [1, "ps-biz-host", 3, "chat-open"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-new-prediction", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "ps-biz-host"], [1, "ps-biz-main"], ["data-testid", "ps-predictions-copilot", 1, "ps-biz-copilot"], ["data-testid", "ps-predictions-empty", 1, "ps-biz-empty"], ["data-testid", "ps-predictions-grid", 1, "ps-biz-grid"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "muted"], ["mjButton", "", "variant", "primary", "size", "md", 3, "click"], ["data-testid", "ps-prediction-card", 1, "ps-biz-card", 3, "blocked"], ["data-testid", "ps-prediction-card", 1, "ps-biz-card"], [1, "ps-biz-card-top"], ["data-testid", "ps-trust-badge", 1, "ps-trust-badge"], [1, "fa-solid", "fa-shield-halved"], [1, "ps-biz-card-title"], [1, "ps-biz-card-line"], [1, "ps-biz-card-foot"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-open-prediction"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-open-blocked", 3, "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-open-prediction", 3, "click"], [1, "fa-solid", "fa-arrow-right"], [1, "fa-solid", "fa-lock"], [1, "ps-biz-crumb"], ["data-testid", "ps-crumb-home", 3, "click"], [1, "fa-solid", "fa-chevron-right"], ["data-testid", "ps-trust-banner", 1, "ps-trust-banner"], [1, "ps-trust-dots"], [1, "fa-solid", "fa-star", 3, "on"], [1, "ps-trust-text"], [1, "ps-trust-grade"], [1, "ps-trust-line"], [1, "ps-trust-explain", "muted"], [1, "ps-trust-evidence", "muted"], ["data-testid", "ps-workspace-body", 1, "ps-biz-workspace-body"], ["data-testid", "ps-action-bar", 1, "ps-action-bar"], [1, "ps-action-locked"], [1, "fa-solid", "fa-star"], ["data-testid", "ps-drivers", 1, "ps-drivers"], ["text", "Loading who's at risk\u2026", "size", "small"], ["data-testid", "ps-atrisk-list", 1, "ps-atrisk"], ["data-testid", "ps-atrisk-empty", 1, "ps-atrisk-empty", "muted"], [1, "fa-solid", "fa-lightbulb"], [1, "ps-driver-chip"], [1, "ps-atrisk-head"], [1, "ps-atrisk-rcol"], ["data-testid", "ps-atrisk-row", 1, "ps-atrisk-row"], [1, "ps-atrisk-foot", "muted"], [1, "ps-atrisk-id", "mono"], [1, "ps-atrisk-bar"], [1, "ps-atrisk-fill"], [1, "ps-atrisk-pct"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-act-review", 3, "click"], [1, "fa-solid", "fa-list-check"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-act-save", 3, "click"], [1, "fa-solid", "fa-floppy-disk"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-act-list", 3, "click"], [1, "fa-solid", "fa-paper-plane"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-act-export", 3, "click", "disabled"], [1, "fa-solid", "fa-file-export"], [1, "ps-biz-copilot-head"], [1, "ps-biz-copilot-title"], [1, "fa-solid", "fa-robot"], ["aria-label", "Close", 1, "ps-biz-copilot-close", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "ps-biz-copilot-body"], ["emptyStateGreeting", "What do you want to predict? Describe it in plain words.", 3, "Provider", "environmentId", "currentUser", "conversation", "conversationId", "isNewConversation", "suppressNewConversationEmptyState", "allowMentions", "overlayMode", "showExportButton", "showShareButton", "showArtifactIndicator", "showAgentPicker", "showAgentModePicker", "defaultAgentId", "pendingMessage", "applicationScope", "applicationId", "appContext"], [1, "ps-biz-copilot-empty"], ["emptyStateGreeting", "What do you want to predict? Describe it in plain words.", 3, "conversationCreated", "pendingMessageConsumed", "Provider", "environmentId", "currentUser", "conversation", "conversationId", "isNewConversation", "suppressNewConversationEmptyState", "allowMentions", "overlayMode", "showExportButton", "showShareButton", "showArtifactIndicator", "showAgentPicker", "showAgentModePicker", "defaultAgentId", "pendingMessage", "applicationScope", "applicationId", "appContext"], ["text", "Connecting\u2026", "size", "small"]], template: function PSPredictionsResourceComponent_Template(rf, ctx) { if (rf & 1) {
894
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PSPredictionsResourceComponent, selectors: [["mj-ps-predictions-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 7, vars: 6, consts: [["atriskList", ""], [3, "Title", "Subtitle"], ["actions", ""], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-new-prediction"], [3, "Flex", "Padding"], ["text", "Loading your predictions\u2026", "size", "medium"], ["data-testid", "ps-load-error", "role", "alert", 1, "ps-load-error"], [1, "ps-biz-host", 3, "chat-open"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-new-prediction", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "ps-load-error-text"], [1, "ps-load-error-detail"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-rotate-right"], [1, "ps-biz-host"], [1, "ps-biz-main"], ["data-testid", "ps-predictions-copilot", 1, "ps-biz-copilot"], ["data-testid", "ps-predictions-empty", 1, "ps-biz-intro"], ["data-testid", "ps-predictions-grid", 1, "ps-biz-grid"], [1, "ps-biz-intro-head"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "ps-cap-grid"], [1, "ps-cap-card"], ["mjButton", "", "variant", "primary", "size", "md", "data-testid", "ps-intro-build", 3, "click"], [1, "ps-cap-title"], [1, "ps-cap-blurb"], ["data-testid", "ps-prediction-card", 1, "ps-biz-card", 3, "blocked"], ["data-testid", "ps-prediction-card", 1, "ps-biz-card"], [1, "ps-biz-card-top"], ["data-testid", "ps-trust-badge", 1, "ps-trust-badge"], [1, "fa-solid", "fa-shield-halved"], [1, "ps-biz-card-title"], [1, "ps-biz-card-line"], [1, "ps-biz-card-foot"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-open-prediction"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-improve-prediction"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-open-prediction", 3, "click"], [1, "fa-solid", "fa-arrow-right"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-improve-prediction", 3, "click"], [1, "ps-biz-crumb"], ["data-testid", "ps-crumb-home", 3, "click"], [1, "fa-solid", "fa-chevron-right"], ["data-testid", "ps-trust-banner", 1, "ps-trust-banner"], [1, "ps-trust-dots"], [1, "fa-solid", "fa-star", 3, "on"], [1, "ps-trust-text"], [1, "ps-trust-grade"], [1, "ps-trust-line"], [1, "ps-trust-explain", "muted"], [1, "ps-trust-evidence", "muted"], ["data-testid", "ps-workspace-body", 1, "ps-biz-workspace-body"], ["data-testid", "ps-action-bar", 1, "ps-action-bar"], [1, "ps-action-locked"], ["data-testid", "ps-list-result", 1, "ps-list-result", "muted"], [1, "fa-solid", "fa-star"], ["data-testid", "ps-drivers", 1, "ps-drivers"], ["text", "Loading who's at risk\u2026", "size", "small"], ["data-testid", "ps-atrisk-error", "role", "alert", 1, "ps-atrisk-error"], ["data-testid", "ps-atrisk-list", 1, "ps-atrisk"], ["data-testid", "ps-atrisk-empty", 1, "ps-atrisk-empty", "muted"], [1, "fa-solid", "fa-lightbulb"], [1, "ps-driver-chip"], [1, "ps-atrisk-error-msg"], [1, "ps-atrisk-head"], [1, "ps-atrisk-rcol"], ["data-testid", "ps-atrisk-row", 1, "ps-atrisk-row"], [1, "ps-atrisk-foot", "muted"], [1, "ps-atrisk-idcell"], [1, "ps-atrisk-id", 3, "title"], ["data-testid", "ps-atrisk-why", 1, "ps-atrisk-why"], [1, "ps-atrisk-bar"], [1, "ps-atrisk-fill"], [1, "ps-atrisk-pct"], [1, "ps-why-chip", 3, "up", "down", "title"], [1, "ps-why-chip", 3, "title"], [1, "fa-solid"], ["mjButton", "", "variant", "primary", "size", "sm", "data-testid", "ps-act-review", 3, "click"], [1, "fa-solid", "fa-list-check"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-act-save", 3, "click"], [1, "fa-solid", "fa-floppy-disk"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-act-list", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", "data-testid", "ps-act-export", 3, "click", "disabled"], [1, "fa-solid", "fa-file-export"], [1, "fa-solid", "fa-lock"], [1, "ps-biz-copilot-head"], [1, "ps-biz-copilot-title"], [1, "fa-solid", "fa-robot"], ["aria-label", "Close", 1, "ps-biz-copilot-close", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "ps-biz-copilot-body"], [3, "Provider", "environmentId", "currentUser", "conversation", "conversationId", "isNewConversation", "suppressNewConversationEmptyState", "allowMentions", "overlayMode", "showExportButton", "showShareButton", "showArtifactIndicator", "showAgentPicker", "showAgentModePicker", "defaultAgentId", "pendingMessage", "applicationScope", "applicationId", "appContext"], [1, "ps-biz-copilot-empty"], [3, "conversationCreated", "pendingMessageConsumed", "Provider", "environmentId", "currentUser", "conversation", "conversationId", "isNewConversation", "suppressNewConversationEmptyState", "allowMentions", "overlayMode", "showExportButton", "showShareButton", "showArtifactIndicator", "showAgentPicker", "showAgentModePicker", "defaultAgentId", "pendingMessage", "applicationScope", "applicationId", "appContext"], ["text", "Connecting\u2026", "size", "small"]], template: function PSPredictionsResourceComponent_Template(rf, ctx) { if (rf & 1) {
508
895
  i0.ɵɵelementStart(0, "mj-page-header-interior", 1)(1, "div", 2);
509
896
  i0.ɵɵconditionalCreate(2, PSPredictionsResourceComponent_Conditional_2_Template, 3, 0, "button", 3);
510
897
  i0.ɵɵelementEnd()();
511
- i0.ɵɵelementStart(3, "mj-page-body-interior");
512
- i0.ɵɵconditionalCreate(4, PSPredictionsResourceComponent_Conditional_4_Template, 1, 0, "mj-loading", 4)(5, PSPredictionsResourceComponent_Conditional_5_Template, 5, 5, "div", 5);
898
+ i0.ɵɵelementStart(3, "mj-page-body-interior", 4);
899
+ i0.ɵɵconditionalCreate(4, PSPredictionsResourceComponent_Conditional_4_Template, 1, 0, "mj-loading", 5)(5, PSPredictionsResourceComponent_Conditional_5_Template, 10, 2, "div", 6)(6, PSPredictionsResourceComponent_Conditional_6_Template, 5, 5, "div", 7);
513
900
  i0.ɵɵelementEnd();
514
901
  } if (rf & 2) {
515
902
  i0.ɵɵproperty("Title", ctx.view === "workspace" ? (ctx.selected == null ? null : ctx.selected.title) ?? "Prediction" : "Predictions")("Subtitle", ctx.view === "workspace" ? "Who to focus on, how much to trust it, and what to do next" : "Ready-to-use predictions for your members");
516
903
  i0.ɵɵadvance(2);
517
904
  i0.ɵɵconditional(ctx.view === "catalog" ? 2 : -1);
518
- i0.ɵɵadvance(2);
519
- i0.ɵɵconditional(ctx.isLoading ? 4 : 5);
520
- } }, dependencies: [i1.MJButtonDirective, i1.MJPageHeaderInteriorComponent, i1.MJPageBodyInteriorComponent, i2.LoadingComponent, i3.ConversationChatAreaComponent], styles: ["[_nghost-%COMP%] { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-biz-host[_ngcontent-%COMP%] { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .ps-biz-main[_ngcontent-%COMP%] { flex: 1; min-width: 0; overflow-y: auto; padding: 16px 18px 28px; }\n .ps-biz-grid[_ngcontent-%COMP%] { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }\n .ps-biz-card[_ngcontent-%COMP%] { background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-lg); padding: 18px; box-shadow: var(--mj-shadow-sm); display: flex; flex-direction: column; gap: 10px; transition: box-shadow .15s, transform .15s; }\n .ps-biz-card[_ngcontent-%COMP%]:hover { box-shadow: var(--mj-shadow-md); transform: translateY(-2px); }\n .ps-biz-card.blocked[_ngcontent-%COMP%] { opacity: .85; background: var(--mj-bg-surface-card); }\n .ps-biz-card-title[_ngcontent-%COMP%] { font-size: var(--mj-text-lg); font-weight: 600; color: var(--mj-text-primary); margin: 0; }\n .ps-biz-card-line[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); margin: 0; flex: 1; }\n .ps-biz-card-foot[_ngcontent-%COMP%] { display: flex; justify-content: flex-end; }\n .ps-trust-badge[_ngcontent-%COMP%] { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--mj-radius-full); font-size: var(--mj-text-xs); font-weight: 600; }\n .trust-good[_ngcontent-%COMP%], .trust-excellent[_ngcontent-%COMP%] { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .trust-fair[_ngcontent-%COMP%] { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .trust-poor[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .ps-biz-empty[_ngcontent-%COMP%] { text-align: center; padding: 64px 16px; color: var(--mj-text-secondary); }\n .ps-biz-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 40px; color: var(--mj-brand-primary); margin-bottom: 12px; }\n .ps-biz-empty[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { margin: 0 0 6px; color: var(--mj-text-primary); }\n .ps-biz-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] { margin: 0 0 16px; }\n .ps-biz-crumb[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; font-size: var(--mj-text-sm); color: var(--mj-text-muted); margin-bottom: 14px; }\n .ps-biz-crumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] { color: var(--mj-text-link); cursor: pointer; }\n .ps-biz-crumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n .ps-biz-crumb[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 10px; }\n .ps-trust-banner[_ngcontent-%COMP%] { display: flex; gap: 16px; align-items: center; padding: 18px 20px; border-radius: var(--mj-radius-lg); border: 1px solid; margin-bottom: 18px; }\n .ps-trust-banner.trust-good[_ngcontent-%COMP%], .ps-trust-banner.trust-excellent[_ngcontent-%COMP%] { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); }\n .ps-trust-banner.trust-fair[_ngcontent-%COMP%] { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); }\n .ps-trust-banner.trust-poor[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-trust-dots[_ngcontent-%COMP%] { display: flex; gap: 3px; font-size: 18px; }\n .ps-trust-dots[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-border-strong); } .ps-trust-dots[_ngcontent-%COMP%] i.on[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n .ps-trust-banner.trust-good[_ngcontent-%COMP%] .ps-trust-dots[_ngcontent-%COMP%] i.on[_ngcontent-%COMP%], .ps-trust-banner.trust-excellent[_ngcontent-%COMP%] .ps-trust-dots[_ngcontent-%COMP%] i.on[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n .ps-trust-grade[_ngcontent-%COMP%] { font-weight: 700; font-size: var(--mj-text-lg); color: var(--mj-text-primary); }\n .ps-trust-line[_ngcontent-%COMP%] { font-weight: 600; color: var(--mj-text-primary); margin-top: 2px; }\n .ps-trust-explain[_ngcontent-%COMP%], .ps-trust-evidence[_ngcontent-%COMP%] { font-size: var(--mj-text-sm); margin-top: 4px; }\n .ps-action-bar[_ngcontent-%COMP%] { display: flex; gap: 10px; flex-wrap: wrap; padding: 14px 16px; border-radius: var(--mj-radius-lg); background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); }\n .ps-action-bar.locked[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-action-locked[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; color: var(--mj-status-error-text); font-weight: 600; font-size: var(--mj-text-sm); }\n .ps-drivers[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 0 0 16px; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); }\n .ps-drivers[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n .ps-driver-chip[_ngcontent-%COMP%] { background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-full); padding: 2px 10px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-atrisk[_ngcontent-%COMP%] { border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-lg); overflow: hidden; margin-bottom: 16px; background: var(--mj-bg-surface); }\n .ps-atrisk-head[_ngcontent-%COMP%] { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; padding: 8px 14px; background: var(--mj-bg-surface-card); border-bottom: 1px solid var(--mj-border-default); font-size: var(--mj-text-xs); font-weight: 600; color: var(--mj-text-muted); text-transform: uppercase; letter-spacing: .03em; }\n .ps-atrisk-rcol[_ngcontent-%COMP%] { grid-column: 2 / span 2; text-align: right; }\n .ps-atrisk-row[_ngcontent-%COMP%] { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; align-items: center; padding: 9px 14px; border-bottom: 1px solid var(--mj-border-subtle); }\n .ps-atrisk-row[_ngcontent-%COMP%]:last-child { border-bottom: none; }\n .ps-atrisk-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n .ps-atrisk-id[_ngcontent-%COMP%] { font-size: var(--mj-text-xs); color: var(--mj-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .ps-atrisk-bar[_ngcontent-%COMP%] { height: 8px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n .ps-atrisk-fill[_ngcontent-%COMP%] { display: block; height: 100%; border-radius: var(--mj-radius-full); }\n .ps-atrisk-pct[_ngcontent-%COMP%] { text-align: right; font-weight: 700; font-size: var(--mj-text-sm); font-variant-numeric: tabular-nums; }\n .ps-atrisk-fill.risk-high[_ngcontent-%COMP%] { background: var(--mj-status-error); }\n .ps-atrisk-fill.risk-medium[_ngcontent-%COMP%] { background: var(--mj-status-warning); }\n .ps-atrisk-fill.risk-low[_ngcontent-%COMP%] { background: var(--mj-status-success); }\n .ps-atrisk-pct.risk-high[_ngcontent-%COMP%] { color: var(--mj-status-error-text); }\n .ps-atrisk-pct.risk-medium[_ngcontent-%COMP%] { color: var(--mj-status-warning-text); }\n .ps-atrisk-pct.risk-low[_ngcontent-%COMP%] { color: var(--mj-status-success-text); }\n .ps-atrisk-foot[_ngcontent-%COMP%] { padding: 8px 14px; font-size: var(--mj-text-xs); }\n .ps-atrisk-empty[_ngcontent-%COMP%] { padding: 24px; text-align: center; border: 1px dashed var(--mj-border-default); border-radius: var(--mj-radius-lg); margin-bottom: 16px; }\n .mono[_ngcontent-%COMP%] { font-family: var(--mj-font-family-mono); }\n .ps-biz-copilot[_ngcontent-%COMP%] { width: 420px; max-width: 42vw; flex: none; border-left: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); display: flex; flex-direction: column; min-height: 0; }\n .ps-biz-copilot-head[_ngcontent-%COMP%] { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--mj-border-default); }\n .ps-biz-copilot-title[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-biz-copilot-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n .ps-biz-copilot-close[_ngcontent-%COMP%] { background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; color: var(--mj-text-muted); }\n .ps-biz-copilot-close[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-secondary); }\n .ps-biz-copilot-body[_ngcontent-%COMP%] { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }\n .ps-biz-copilot-body[_ngcontent-%COMP%] mj-conversation-chat-area[_ngcontent-%COMP%] { flex: 1; min-height: 0; display: block; }\n .ps-biz-copilot-empty[_ngcontent-%COMP%] { display: flex; align-items: center; justify-content: center; flex: 1; }\n @media (max-width: 1100px) { .ps-biz-host.chat-open[_ngcontent-%COMP%] .ps-biz-main[_ngcontent-%COMP%] { display: none; } .ps-biz-copilot[_ngcontent-%COMP%] { width: 100%; max-width: none; border-left: none; } }"], changeDetection: 0 });
905
+ i0.ɵɵadvance();
906
+ i0.ɵɵproperty("Flex", true)("Padding", false);
907
+ i0.ɵɵadvance();
908
+ i0.ɵɵconditional(ctx.isLoading ? 4 : ctx.loadError ? 5 : 6);
909
+ } }, dependencies: [i1.MJButtonDirective, i1.MJPageHeaderInteriorComponent, i1.MJPageBodyInteriorComponent, i2.LoadingComponent, i3.ConversationChatAreaComponent], styles: ["[_nghost-%COMP%] { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-biz-host[_ngcontent-%COMP%] { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .ps-biz-main[_ngcontent-%COMP%] { flex: 1; min-width: 0; overflow-y: auto; padding: 16px 18px 28px; }\n .ps-biz-grid[_ngcontent-%COMP%] { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }\n .ps-biz-card[_ngcontent-%COMP%] { background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md); padding: 18px; display: flex; flex-direction: column; gap: 10px; transition: border-color .12s, background .12s; }\n .ps-biz-card[_ngcontent-%COMP%]:hover { border-color: var(--mj-brand-primary); background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface)); }\n .ps-biz-card.blocked[_ngcontent-%COMP%] { opacity: .85; background: var(--mj-bg-surface-card); }\n .ps-biz-card-title[_ngcontent-%COMP%] { font-size: var(--mj-text-lg); font-weight: 600; color: var(--mj-text-primary); margin: 0; }\n .ps-biz-card-line[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); margin: 0; flex: 1; }\n .ps-biz-card-foot[_ngcontent-%COMP%] { display: flex; justify-content: flex-end; }\n .ps-trust-badge[_ngcontent-%COMP%] { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--mj-radius-full); font-size: var(--mj-text-xs); font-weight: 600; }\n .trust-good[_ngcontent-%COMP%], .trust-excellent[_ngcontent-%COMP%] { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .trust-fair[_ngcontent-%COMP%] { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .trust-poor[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .ps-biz-intro[_ngcontent-%COMP%] { max-width: 820px; margin: 32px auto; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 20px; }\n .ps-biz-intro-head[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 40px; color: var(--mj-brand-primary); }\n .ps-biz-intro-head[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] { margin: 12px 0 6px; color: var(--mj-text-primary); font-size: var(--mj-text-xl); }\n .ps-biz-intro-head[_ngcontent-%COMP%] p[_ngcontent-%COMP%] { margin: 0 auto; max-width: 620px; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); }\n .ps-cap-grid[_ngcontent-%COMP%] { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; width: 100%; }\n .ps-cap-card[_ngcontent-%COMP%] { background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md); padding: 18px 16px; text-align: left; display: flex; flex-direction: column; gap: 6px; }\n .ps-cap-card[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 20px; color: var(--mj-brand-primary); }\n .ps-cap-title[_ngcontent-%COMP%] { font-weight: 600; color: var(--mj-text-primary); font-size: var(--mj-text-sm); }\n .ps-cap-blurb[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-size: var(--mj-text-xs); line-height: 1.45; }\n .ps-biz-crumb[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; font-size: var(--mj-text-sm); color: var(--mj-text-muted); margin-bottom: 14px; }\n .ps-biz-crumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] { color: var(--mj-text-link); cursor: pointer; }\n .ps-biz-crumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n .ps-biz-crumb[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 10px; }\n .ps-trust-banner[_ngcontent-%COMP%] { display: flex; gap: 16px; align-items: center; padding: 18px 20px; border-radius: var(--mj-radius-md); border: 1px solid; margin-bottom: 18px; }\n .ps-trust-banner.trust-good[_ngcontent-%COMP%], .ps-trust-banner.trust-excellent[_ngcontent-%COMP%] { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); }\n .ps-trust-banner.trust-fair[_ngcontent-%COMP%] { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); }\n .ps-trust-banner.trust-poor[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-trust-dots[_ngcontent-%COMP%] { display: flex; gap: 3px; font-size: 18px; }\n .ps-trust-dots[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-border-strong); } .ps-trust-dots[_ngcontent-%COMP%] i.on[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n .ps-trust-banner.trust-good[_ngcontent-%COMP%] .ps-trust-dots[_ngcontent-%COMP%] i.on[_ngcontent-%COMP%], .ps-trust-banner.trust-excellent[_ngcontent-%COMP%] .ps-trust-dots[_ngcontent-%COMP%] i.on[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n .ps-trust-grade[_ngcontent-%COMP%] { font-weight: 700; font-size: var(--mj-text-lg); color: var(--mj-text-primary); }\n .ps-trust-line[_ngcontent-%COMP%] { font-weight: 600; color: var(--mj-text-primary); margin-top: 2px; }\n .ps-trust-explain[_ngcontent-%COMP%], .ps-trust-evidence[_ngcontent-%COMP%] { font-size: var(--mj-text-sm); margin-top: 4px; }\n .ps-action-bar[_ngcontent-%COMP%] { display: flex; gap: 10px; flex-wrap: wrap; padding: 14px 16px; border-radius: var(--mj-radius-md); background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); }\n .ps-action-bar.locked[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-action-locked[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; color: var(--mj-status-error-text); font-weight: 600; font-size: var(--mj-text-sm); }\n .ps-drivers[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 0 0 16px; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); }\n .ps-drivers[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n .ps-driver-chip[_ngcontent-%COMP%] { background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-full); padding: 2px 10px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-atrisk[_ngcontent-%COMP%] { border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md); overflow: hidden; margin-bottom: 16px; background: var(--mj-bg-surface); }\n .ps-atrisk-head[_ngcontent-%COMP%] { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; padding: 8px 14px; background: var(--mj-bg-surface-card); border-bottom: 1px solid var(--mj-border-default); font-size: var(--mj-text-xs); font-weight: 600; color: var(--mj-text-muted); text-transform: uppercase; letter-spacing: .03em; }\n .ps-atrisk-rcol[_ngcontent-%COMP%] { grid-column: 2 / span 2; text-align: right; }\n .ps-atrisk-row[_ngcontent-%COMP%] { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; align-items: center; padding: 9px 14px; border-bottom: 1px solid var(--mj-border-subtle); }\n .ps-atrisk-row[_ngcontent-%COMP%]:last-child { border-bottom: none; }\n .ps-atrisk-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n .ps-atrisk-idcell[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n .ps-atrisk-id[_ngcontent-%COMP%] { font-size: var(--mj-text-xs); color: var(--mj-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .ps-atrisk-why[_ngcontent-%COMP%] { display: flex; gap: 6px; flex-wrap: wrap; }\n .ps-why-chip[_ngcontent-%COMP%] { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 600; padding: 1px 7px; border-radius: var(--mj-radius-full); max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .ps-why-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 8px; }\n .ps-why-chip.up[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .ps-why-chip.down[_ngcontent-%COMP%] { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .ps-atrisk-bar[_ngcontent-%COMP%] { height: 8px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n .ps-atrisk-fill[_ngcontent-%COMP%] { display: block; height: 100%; border-radius: var(--mj-radius-full); }\n .ps-atrisk-pct[_ngcontent-%COMP%] { text-align: right; font-weight: 700; font-size: var(--mj-text-sm); font-variant-numeric: tabular-nums; }\n .ps-atrisk-fill.risk-high[_ngcontent-%COMP%] { background: var(--mj-status-error); }\n .ps-atrisk-fill.risk-medium[_ngcontent-%COMP%] { background: var(--mj-status-warning); }\n .ps-atrisk-fill.risk-low[_ngcontent-%COMP%] { background: var(--mj-status-success); }\n .ps-atrisk-pct.risk-high[_ngcontent-%COMP%] { color: var(--mj-status-error-text); }\n .ps-atrisk-pct.risk-medium[_ngcontent-%COMP%] { color: var(--mj-status-warning-text); }\n .ps-atrisk-pct.risk-low[_ngcontent-%COMP%] { color: var(--mj-status-success-text); }\n .ps-atrisk-foot[_ngcontent-%COMP%] { padding: 8px 14px; font-size: var(--mj-text-xs); }\n .ps-atrisk-empty[_ngcontent-%COMP%] { padding: 24px; text-align: center; border: 1px dashed var(--mj-border-default); border-radius: var(--mj-radius-md); margin-bottom: 16px; }\n .ps-atrisk-error[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 10px; padding: 16px 18px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-md); margin-bottom: 16px; color: var(--mj-status-error-text); font-size: var(--mj-text-sm); }\n .ps-atrisk-error[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n .ps-atrisk-error[_ngcontent-%COMP%] .ps-atrisk-error-msg[_ngcontent-%COMP%] { flex: 1; min-width: 0; word-break: break-word; }\n .mono[_ngcontent-%COMP%] { font-family: var(--mj-font-family-mono); }\n \n\n\n .ps-load-error[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 14px; max-width: 620px; margin: 32px auto; padding: 18px 20px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-lg); }\n .ps-load-error[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] { font-size: 24px; color: var(--mj-status-error); }\n .ps-load-error-text[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n .ps-load-error-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] { color: var(--mj-text-primary); }\n .ps-load-error-detail[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); word-break: break-word; }\n .ps-biz-copilot[_ngcontent-%COMP%] { width: 560px; min-width: 380px; max-width: 60vw; flex: none; border-left: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); display: flex; flex-direction: column; min-height: 0; }\n .ps-biz-copilot-head[_ngcontent-%COMP%] { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--mj-border-default); }\n .ps-biz-copilot-title[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-biz-copilot-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n .ps-biz-copilot-close[_ngcontent-%COMP%] { background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; color: var(--mj-text-muted); }\n .ps-biz-copilot-close[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-secondary); }\n .ps-biz-copilot-body[_ngcontent-%COMP%] { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }\n .ps-biz-copilot-body[_ngcontent-%COMP%] mj-conversation-chat-area[_ngcontent-%COMP%] { flex: 1; min-height: 0; display: block; }\n .ps-biz-copilot-empty[_ngcontent-%COMP%] { display: flex; align-items: center; justify-content: center; flex: 1; }\n @media (max-width: 1100px) { .ps-biz-host.chat-open[_ngcontent-%COMP%] .ps-biz-main[_ngcontent-%COMP%] { display: none; } .ps-biz-copilot[_ngcontent-%COMP%] { width: 100%; max-width: none; border-left: none; } }"], changeDetection: 0 });
521
910
  };
522
911
  PSPredictionsResourceComponent = __decorate([
523
912
  RegisterClass(BaseResourceComponent, 'PredictiveStudioPredictionsResource')
@@ -537,20 +926,40 @@ export { PSPredictionsResourceComponent };
537
926
  }
538
927
  </div>
539
928
  </mj-page-header-interior>
540
- <mj-page-body-interior>
929
+ <mj-page-body-interior [Flex]="true" [Padding]="false">
541
930
  @if (isLoading) {
542
931
  <mj-loading text="Loading your predictions…" size="medium"></mj-loading>
932
+ } @else if (loadError) {
933
+ <div class="ps-load-error" data-testid="ps-load-error" role="alert">
934
+ <i class="fa-solid fa-triangle-exclamation"></i>
935
+ <div class="ps-load-error-text">
936
+ <strong>Couldn't load {{ sectionTitle }}</strong>
937
+ <span class="ps-load-error-detail">{{ loadError }}</span>
938
+ </div>
939
+ <button mjButton variant="secondary" size="sm" (click)="retryLoad()"><i class="fa-solid fa-rotate-right"></i> Try again</button>
940
+ </div>
543
941
  } @else {
544
942
  <div class="ps-biz-host" [class.chat-open]="chatOpen">
545
943
  <div class="ps-biz-main">
546
944
  <!-- ───────── CATALOG ───────── -->
547
945
  @if (view === 'catalog') {
548
946
  @if (cards.length === 0) {
549
- <div class="ps-biz-empty" data-testid="ps-predictions-empty">
550
- <i class="fa-solid fa-wand-magic-sparkles"></i>
551
- <h3>No predictions yet</h3>
552
- <p class="muted">Ask the Model Dev Agent to build your first one.</p>
553
- <button mjButton variant="primary" size="md" (click)="newPrediction()"><i class="fa-solid fa-plus"></i> New prediction</button>
947
+ <div class="ps-biz-intro" data-testid="ps-predictions-empty">
948
+ <div class="ps-biz-intro-head">
949
+ <i class="fa-solid fa-wand-magic-sparkles"></i>
950
+ <h2>Predict what's next for your data</h2>
951
+ <p>Predictive Studio turns your records into plain-language predictions — describe what you want to know, and the agent builds and trains a model with you. Here's what you can do:</p>
952
+ </div>
953
+ <div class="ps-cap-grid">
954
+ @for (cap of capabilityCards; track cap.title) {
955
+ <div class="ps-cap-card">
956
+ <i [class]="cap.icon"></i>
957
+ <div class="ps-cap-title">{{ cap.title }}</div>
958
+ <div class="ps-cap-blurb">{{ cap.blurb }}</div>
959
+ </div>
960
+ }
961
+ </div>
962
+ <button mjButton variant="primary" size="md" data-testid="ps-intro-build" (click)="newPrediction()"><i class="fa-solid fa-plus"></i> Build your first prediction</button>
554
963
  </div>
555
964
  } @else {
556
965
  <div class="ps-biz-grid" data-testid="ps-predictions-grid">
@@ -567,7 +976,7 @@ export { PSPredictionsResourceComponent };
567
976
  @if (c.canOpen) {
568
977
  <button mjButton variant="secondary" size="sm" data-testid="ps-open-prediction" (click)="open(c)">Open <i class="fa-solid fa-arrow-right"></i></button>
569
978
  } @else {
570
- <button mjButton variant="secondary" size="sm" [disabled]="true" data-testid="ps-open-blocked"><i class="fa-solid fa-lock"></i> Needs an analyst</button>
979
+ <button mjButton variant="secondary" size="sm" data-testid="ps-improve-prediction" (click)="improvePrediction(c)"><i class="fa-solid fa-wand-magic-sparkles"></i> Improve this</button>
571
980
  }
572
981
  </div>
573
982
  </div>
@@ -605,12 +1014,29 @@ export { PSPredictionsResourceComponent };
605
1014
  }
606
1015
  @if (atRiskLoading) {
607
1016
  <mj-loading text="Loading who's at risk…" size="small"></mj-loading>
1017
+ } @else if (atRiskError) {
1018
+ <div class="ps-atrisk-error" data-testid="ps-atrisk-error" role="alert">
1019
+ <i class="fa-solid fa-triangle-exclamation"></i>
1020
+ <span class="ps-atrisk-error-msg">Couldn't load who's at risk: {{ atRiskError }}</span>
1021
+ <button mjButton variant="secondary" size="sm" (click)="retryAtRisk()"><i class="fa-solid fa-rotate-right"></i> Try again</button>
1022
+ </div>
608
1023
  } @else if (atRiskRows.length > 0) {
609
1024
  <div class="ps-atrisk" data-testid="ps-atrisk-list" #atriskList>
610
1025
  <div class="ps-atrisk-head"><span>Member</span><span class="ps-atrisk-rcol">Likelihood</span></div>
611
1026
  @for (r of atRiskRows.slice(0, 50); track r.recordId) {
612
1027
  <div class="ps-atrisk-row" data-testid="ps-atrisk-row">
613
- <span class="ps-atrisk-id mono">{{ r.recordId }}</span>
1028
+ <div class="ps-atrisk-idcell">
1029
+ <span class="ps-atrisk-id" [class.mono]="!r.label" [title]="r.recordId">{{ r.label || r.recordId }}</span>
1030
+ @if (r.drivers && r.drivers.length > 0) {
1031
+ <span class="ps-atrisk-why" data-testid="ps-atrisk-why">
1032
+ @for (d of r.drivers.slice(0, 2); track d.label) {
1033
+ <span class="ps-why-chip" [class.up]="d.up" [class.down]="!d.up" [title]="(d.up ? 'Increases risk: ' : 'Lowers risk: ') + d.label">
1034
+ <i class="fa-solid" [class.fa-arrow-up]="d.up" [class.fa-arrow-down]="!d.up"></i> {{ d.label }}
1035
+ </span>
1036
+ }
1037
+ </span>
1038
+ }
1039
+ </div>
614
1040
  <span class="ps-atrisk-bar"><span class="ps-atrisk-fill" [class]="'risk-' + r.band" [style.width.%]="r.riskPct"></span></span>
615
1041
  <span class="ps-atrisk-pct" [class]="'risk-' + r.band">{{ r.riskPct }}%</span>
616
1042
  </div>
@@ -625,12 +1051,13 @@ export { PSPredictionsResourceComponent };
625
1051
  @if (selected.canOpen) {
626
1052
  <button mjButton variant="primary" size="sm" data-testid="ps-act-review" (click)="scrollToList()"><i class="fa-solid fa-list-check"></i> Review the call list</button>
627
1053
  <button mjButton variant="secondary" size="sm" data-testid="ps-act-save" (click)="askAgentTo('Save these renewal-risk scores onto the member records so my team can use them.')"><i class="fa-solid fa-floppy-disk"></i> Save scores to records</button>
628
- <button mjButton variant="secondary" size="sm" data-testid="ps-act-list" (click)="askAgentTo('Put these at-risk members into a list called &quot;At-Risk Renewals&quot; for outreach.')"><i class="fa-solid fa-paper-plane"></i> Send to a list</button>
1054
+ <button mjButton variant="secondary" size="sm" data-testid="ps-act-list" [disabled]="creatingList || atRiskRows.length === 0" (click)="sendToList()"><i class="fa-solid" [class.fa-paper-plane]="!creatingList" [class.fa-spinner]="creatingList" [class.fa-spin]="creatingList"></i> Send to a list</button>
629
1055
  <button mjButton variant="secondary" size="sm" data-testid="ps-act-export" [disabled]="atRiskRows.length === 0" (click)="exportList()"><i class="fa-solid fa-file-export"></i> Share / export</button>
630
1056
  } @else {
631
1057
  <div class="ps-action-locked"><i class="fa-solid fa-lock"></i> {{ selected.trust.gateReason }}</div>
632
1058
  }
633
1059
  </div>
1060
+ @if (listResult) { <div class="ps-list-result muted" data-testid="ps-list-result">{{ listResult }}</div> }
634
1061
  </div>
635
1062
  }
636
1063
  </div>
@@ -652,8 +1079,7 @@ export { PSPredictionsResourceComponent };
652
1079
  [defaultAgentId]="modelDevAgentId" [pendingMessage]="pendingPrompt"
653
1080
  [applicationScope]="'Application'" [applicationId]="applicationId" [appContext]="chatAppContext"
654
1081
  (conversationCreated)="onChatConversationCreated($event)"
655
- (pendingMessageConsumed)="onChatPendingMessageConsumed()"
656
- emptyStateGreeting="What do you want to predict? Describe it in plain words.">
1082
+ (pendingMessageConsumed)="onChatPendingMessageConsumed()">
657
1083
  </mj-conversation-chat-area>
658
1084
  } @else { <div class="ps-biz-copilot-empty"><mj-loading text="Connecting…" size="small"></mj-loading></div> }
659
1085
  </div>
@@ -662,9 +1088,9 @@ export { PSPredictionsResourceComponent };
662
1088
  </div>
663
1089
  }
664
1090
  </mj-page-body-interior>
665
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-biz-host { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .ps-biz-main { flex: 1; min-width: 0; overflow-y: auto; padding: 16px 18px 28px; }\n .ps-biz-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }\n .ps-biz-card { background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-lg); padding: 18px; box-shadow: var(--mj-shadow-sm); display: flex; flex-direction: column; gap: 10px; transition: box-shadow .15s, transform .15s; }\n .ps-biz-card:hover { box-shadow: var(--mj-shadow-md); transform: translateY(-2px); }\n .ps-biz-card.blocked { opacity: .85; background: var(--mj-bg-surface-card); }\n .ps-biz-card-title { font-size: var(--mj-text-lg); font-weight: 600; color: var(--mj-text-primary); margin: 0; }\n .ps-biz-card-line { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); margin: 0; flex: 1; }\n .ps-biz-card-foot { display: flex; justify-content: flex-end; }\n .ps-trust-badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--mj-radius-full); font-size: var(--mj-text-xs); font-weight: 600; }\n .trust-good, .trust-excellent { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .trust-fair { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .trust-poor { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .ps-biz-empty { text-align: center; padding: 64px 16px; color: var(--mj-text-secondary); }\n .ps-biz-empty i { font-size: 40px; color: var(--mj-brand-primary); margin-bottom: 12px; }\n .ps-biz-empty h3 { margin: 0 0 6px; color: var(--mj-text-primary); }\n .ps-biz-empty p { margin: 0 0 16px; }\n .ps-biz-crumb { display: flex; align-items: center; gap: 8px; font-size: var(--mj-text-sm); color: var(--mj-text-muted); margin-bottom: 14px; }\n .ps-biz-crumb a { color: var(--mj-text-link); cursor: pointer; }\n .ps-biz-crumb a:hover { text-decoration: underline; }\n .ps-biz-crumb i { font-size: 10px; }\n .ps-trust-banner { display: flex; gap: 16px; align-items: center; padding: 18px 20px; border-radius: var(--mj-radius-lg); border: 1px solid; margin-bottom: 18px; }\n .ps-trust-banner.trust-good, .ps-trust-banner.trust-excellent { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); }\n .ps-trust-banner.trust-fair { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); }\n .ps-trust-banner.trust-poor { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-trust-dots { display: flex; gap: 3px; font-size: 18px; }\n .ps-trust-dots i { color: var(--mj-border-strong); } .ps-trust-dots i.on { color: var(--mj-status-warning); }\n .ps-trust-banner.trust-good .ps-trust-dots i.on, .ps-trust-banner.trust-excellent .ps-trust-dots i.on { color: var(--mj-status-success); }\n .ps-trust-grade { font-weight: 700; font-size: var(--mj-text-lg); color: var(--mj-text-primary); }\n .ps-trust-line { font-weight: 600; color: var(--mj-text-primary); margin-top: 2px; }\n .ps-trust-explain, .ps-trust-evidence { font-size: var(--mj-text-sm); margin-top: 4px; }\n .ps-action-bar { display: flex; gap: 10px; flex-wrap: wrap; padding: 14px 16px; border-radius: var(--mj-radius-lg); background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); }\n .ps-action-bar.locked { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-action-locked { display: flex; align-items: center; gap: 8px; color: var(--mj-status-error-text); font-weight: 600; font-size: var(--mj-text-sm); }\n .ps-drivers { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 0 0 16px; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); }\n .ps-drivers i { color: var(--mj-status-warning); }\n .ps-driver-chip { background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-full); padding: 2px 10px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-atrisk { border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-lg); overflow: hidden; margin-bottom: 16px; background: var(--mj-bg-surface); }\n .ps-atrisk-head { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; padding: 8px 14px; background: var(--mj-bg-surface-card); border-bottom: 1px solid var(--mj-border-default); font-size: var(--mj-text-xs); font-weight: 600; color: var(--mj-text-muted); text-transform: uppercase; letter-spacing: .03em; }\n .ps-atrisk-rcol { grid-column: 2 / span 2; text-align: right; }\n .ps-atrisk-row { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; align-items: center; padding: 9px 14px; border-bottom: 1px solid var(--mj-border-subtle); }\n .ps-atrisk-row:last-child { border-bottom: none; }\n .ps-atrisk-row:hover { background: var(--mj-bg-surface-hover); }\n .ps-atrisk-id { font-size: var(--mj-text-xs); color: var(--mj-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .ps-atrisk-bar { height: 8px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n .ps-atrisk-fill { display: block; height: 100%; border-radius: var(--mj-radius-full); }\n .ps-atrisk-pct { text-align: right; font-weight: 700; font-size: var(--mj-text-sm); font-variant-numeric: tabular-nums; }\n .ps-atrisk-fill.risk-high { background: var(--mj-status-error); }\n .ps-atrisk-fill.risk-medium { background: var(--mj-status-warning); }\n .ps-atrisk-fill.risk-low { background: var(--mj-status-success); }\n .ps-atrisk-pct.risk-high { color: var(--mj-status-error-text); }\n .ps-atrisk-pct.risk-medium { color: var(--mj-status-warning-text); }\n .ps-atrisk-pct.risk-low { color: var(--mj-status-success-text); }\n .ps-atrisk-foot { padding: 8px 14px; font-size: var(--mj-text-xs); }\n .ps-atrisk-empty { padding: 24px; text-align: center; border: 1px dashed var(--mj-border-default); border-radius: var(--mj-radius-lg); margin-bottom: 16px; }\n .mono { font-family: var(--mj-font-family-mono); }\n .ps-biz-copilot { width: 420px; max-width: 42vw; flex: none; border-left: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); display: flex; flex-direction: column; min-height: 0; }\n .ps-biz-copilot-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--mj-border-default); }\n .ps-biz-copilot-title { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-biz-copilot-title i { color: var(--mj-brand-primary); }\n .ps-biz-copilot-close { background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; color: var(--mj-text-muted); }\n .ps-biz-copilot-close:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-secondary); }\n .ps-biz-copilot-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }\n .ps-biz-copilot-body mj-conversation-chat-area { flex: 1; min-height: 0; display: block; }\n .ps-biz-copilot-empty { display: flex; align-items: center; justify-content: center; flex: 1; }\n @media (max-width: 1100px) { .ps-biz-host.chat-open .ps-biz-main { display: none; } .ps-biz-copilot { width: 100%; max-width: none; border-left: none; } }\n "] }]
1091
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-biz-host { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .ps-biz-main { flex: 1; min-width: 0; overflow-y: auto; padding: 16px 18px 28px; }\n .ps-biz-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }\n .ps-biz-card { background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md); padding: 18px; display: flex; flex-direction: column; gap: 10px; transition: border-color .12s, background .12s; }\n .ps-biz-card:hover { border-color: var(--mj-brand-primary); background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface)); }\n .ps-biz-card.blocked { opacity: .85; background: var(--mj-bg-surface-card); }\n .ps-biz-card-title { font-size: var(--mj-text-lg); font-weight: 600; color: var(--mj-text-primary); margin: 0; }\n .ps-biz-card-line { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); margin: 0; flex: 1; }\n .ps-biz-card-foot { display: flex; justify-content: flex-end; }\n .ps-trust-badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--mj-radius-full); font-size: var(--mj-text-xs); font-weight: 600; }\n .trust-good, .trust-excellent { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .trust-fair { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .trust-poor { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .ps-biz-intro { max-width: 820px; margin: 32px auto; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 20px; }\n .ps-biz-intro-head i { font-size: 40px; color: var(--mj-brand-primary); }\n .ps-biz-intro-head h2 { margin: 12px 0 6px; color: var(--mj-text-primary); font-size: var(--mj-text-xl); }\n .ps-biz-intro-head p { margin: 0 auto; max-width: 620px; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); }\n .ps-cap-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; width: 100%; }\n .ps-cap-card { background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md); padding: 18px 16px; text-align: left; display: flex; flex-direction: column; gap: 6px; }\n .ps-cap-card i { font-size: 20px; color: var(--mj-brand-primary); }\n .ps-cap-title { font-weight: 600; color: var(--mj-text-primary); font-size: var(--mj-text-sm); }\n .ps-cap-blurb { color: var(--mj-text-secondary); font-size: var(--mj-text-xs); line-height: 1.45; }\n .ps-biz-crumb { display: flex; align-items: center; gap: 8px; font-size: var(--mj-text-sm); color: var(--mj-text-muted); margin-bottom: 14px; }\n .ps-biz-crumb a { color: var(--mj-text-link); cursor: pointer; }\n .ps-biz-crumb a:hover { text-decoration: underline; }\n .ps-biz-crumb i { font-size: 10px; }\n .ps-trust-banner { display: flex; gap: 16px; align-items: center; padding: 18px 20px; border-radius: var(--mj-radius-md); border: 1px solid; margin-bottom: 18px; }\n .ps-trust-banner.trust-good, .ps-trust-banner.trust-excellent { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); }\n .ps-trust-banner.trust-fair { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); }\n .ps-trust-banner.trust-poor { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-trust-dots { display: flex; gap: 3px; font-size: 18px; }\n .ps-trust-dots i { color: var(--mj-border-strong); } .ps-trust-dots i.on { color: var(--mj-status-warning); }\n .ps-trust-banner.trust-good .ps-trust-dots i.on, .ps-trust-banner.trust-excellent .ps-trust-dots i.on { color: var(--mj-status-success); }\n .ps-trust-grade { font-weight: 700; font-size: var(--mj-text-lg); color: var(--mj-text-primary); }\n .ps-trust-line { font-weight: 600; color: var(--mj-text-primary); margin-top: 2px; }\n .ps-trust-explain, .ps-trust-evidence { font-size: var(--mj-text-sm); margin-top: 4px; }\n .ps-action-bar { display: flex; gap: 10px; flex-wrap: wrap; padding: 14px 16px; border-radius: var(--mj-radius-md); background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); }\n .ps-action-bar.locked { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-action-locked { display: flex; align-items: center; gap: 8px; color: var(--mj-status-error-text); font-weight: 600; font-size: var(--mj-text-sm); }\n .ps-drivers { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 0 0 16px; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); }\n .ps-drivers i { color: var(--mj-status-warning); }\n .ps-driver-chip { background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-full); padding: 2px 10px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-atrisk { border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md); overflow: hidden; margin-bottom: 16px; background: var(--mj-bg-surface); }\n .ps-atrisk-head { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; padding: 8px 14px; background: var(--mj-bg-surface-card); border-bottom: 1px solid var(--mj-border-default); font-size: var(--mj-text-xs); font-weight: 600; color: var(--mj-text-muted); text-transform: uppercase; letter-spacing: .03em; }\n .ps-atrisk-rcol { grid-column: 2 / span 2; text-align: right; }\n .ps-atrisk-row { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; align-items: center; padding: 9px 14px; border-bottom: 1px solid var(--mj-border-subtle); }\n .ps-atrisk-row:last-child { border-bottom: none; }\n .ps-atrisk-row:hover { background: var(--mj-bg-surface-hover); }\n .ps-atrisk-idcell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n .ps-atrisk-id { font-size: var(--mj-text-xs); color: var(--mj-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .ps-atrisk-why { display: flex; gap: 6px; flex-wrap: wrap; }\n .ps-why-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 600; padding: 1px 7px; border-radius: var(--mj-radius-full); max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .ps-why-chip i { font-size: 8px; }\n .ps-why-chip.up { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .ps-why-chip.down { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .ps-atrisk-bar { height: 8px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n .ps-atrisk-fill { display: block; height: 100%; border-radius: var(--mj-radius-full); }\n .ps-atrisk-pct { text-align: right; font-weight: 700; font-size: var(--mj-text-sm); font-variant-numeric: tabular-nums; }\n .ps-atrisk-fill.risk-high { background: var(--mj-status-error); }\n .ps-atrisk-fill.risk-medium { background: var(--mj-status-warning); }\n .ps-atrisk-fill.risk-low { background: var(--mj-status-success); }\n .ps-atrisk-pct.risk-high { color: var(--mj-status-error-text); }\n .ps-atrisk-pct.risk-medium { color: var(--mj-status-warning-text); }\n .ps-atrisk-pct.risk-low { color: var(--mj-status-success-text); }\n .ps-atrisk-foot { padding: 8px 14px; font-size: var(--mj-text-xs); }\n .ps-atrisk-empty { padding: 24px; text-align: center; border: 1px dashed var(--mj-border-default); border-radius: var(--mj-radius-md); margin-bottom: 16px; }\n .ps-atrisk-error { display: flex; align-items: center; gap: 10px; padding: 16px 18px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-md); margin-bottom: 16px; color: var(--mj-status-error-text); font-size: var(--mj-text-sm); }\n .ps-atrisk-error i { color: var(--mj-status-error); }\n .ps-atrisk-error .ps-atrisk-error-msg { flex: 1; min-width: 0; word-break: break-word; }\n .mono { font-family: var(--mj-font-family-mono); }\n /* Kept local (not in the shared stylesheet) deliberately: shared styles are injected by the\n ViewEncapsulation.None PANEL components, and this banner renders precisely when panels DON'T. */\n .ps-load-error { display: flex; align-items: center; gap: 14px; max-width: 620px; margin: 32px auto; padding: 18px 20px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-lg); }\n .ps-load-error > i { font-size: 24px; color: var(--mj-status-error); }\n .ps-load-error-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n .ps-load-error-text strong { color: var(--mj-text-primary); }\n .ps-load-error-detail { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); word-break: break-word; }\n .ps-biz-copilot { width: 560px; min-width: 380px; max-width: 60vw; flex: none; border-left: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); display: flex; flex-direction: column; min-height: 0; }\n .ps-biz-copilot-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--mj-border-default); }\n .ps-biz-copilot-title { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-biz-copilot-title i { color: var(--mj-brand-primary); }\n .ps-biz-copilot-close { background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; color: var(--mj-text-muted); }\n .ps-biz-copilot-close:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-secondary); }\n .ps-biz-copilot-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }\n .ps-biz-copilot-body mj-conversation-chat-area { flex: 1; min-height: 0; display: block; }\n .ps-biz-copilot-empty { display: flex; align-items: center; justify-content: center; flex: 1; }\n @media (max-width: 1100px) { .ps-biz-host.chat-open .ps-biz-main { display: none; } .ps-biz-copilot { width: 100%; max-width: none; border-left: none; } }\n "] }]
666
1092
  }], null, null); })();
667
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PSPredictionsResourceComponent, { className: "PSPredictionsResourceComponent", filePath: "src/PredictiveStudio/resources/ps-predictions-resource.component.ts", lineNumber: 237 }); })();
1093
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PSPredictionsResourceComponent, { className: "PSPredictionsResourceComponent", filePath: "src/PredictiveStudio/resources/ps-predictions-resource.component.ts", lineNumber: 298 }); })();
668
1094
  /** Tree-shaking prevention — called from the subpath module so the @RegisterClass survives bundling. */
669
1095
  export function LoadPSPredictionsResource() {
670
1096
  // intentionally empty