@memberjunction/ng-dashboards 6.1.2 → 6.2.0-edge.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +6 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +99 -45
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +4 -0
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +16 -6
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +4 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +14 -4
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +2 -2
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/DevTools/graphql-console.component.d.ts.map +1 -1
- package/dist/DevTools/graphql-console.component.js +2 -0
- package/dist/DevTools/graphql-console.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +2 -0
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts +4 -12
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js +39 -78
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +3 -0
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +7 -6
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts +3 -0
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +7 -6
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/at-risk.view-models.d.ts +41 -3
- package/dist/PredictiveStudio/at-risk.view-models.d.ts.map +1 -1
- package/dist/PredictiveStudio/at-risk.view-models.js +99 -6
- package/dist/PredictiveStudio/at-risk.view-models.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.d.ts +4 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.js +61 -37
- package/dist/PredictiveStudio/components/ps-catalog.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts +12 -0
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.js +426 -184
- package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts +84 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js +1397 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts +66 -34
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipelines.component.js +2456 -743
- package/dist/PredictiveStudio/components/ps-pipelines.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts +194 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js +1902 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-production.component.d.ts +17 -1
- package/dist/PredictiveStudio/components/ps-production.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-production.component.js +653 -372
- package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-registry.component.d.ts +21 -61
- package/dist/PredictiveStudio/components/ps-registry.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-registry.component.js +214 -681
- package/dist/PredictiveStudio/components/ps-registry.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts +49 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js +658 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js.map +1 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts +42 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts.map +1 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js +90 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js.map +1 -0
- package/dist/PredictiveStudio/predictive-studio.view-models.d.ts +14 -2
- package/dist/PredictiveStudio/predictive-studio.view-models.d.ts.map +1 -1
- package/dist/PredictiveStudio/predictive-studio.view-models.js +41 -5
- package/dist/PredictiveStudio/predictive-studio.view-models.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts +9 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.js +178 -65
- package/dist/PredictiveStudio/resources/ps-models-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts +9 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +307 -369
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-resource-base.js +1 -1
- package/dist/PredictiveStudio/resources/ps-resource-base.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts +17 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js +309 -138
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.d.ts +1 -0
- package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +6 -5
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
- package/dist/predictive-studio-dashboards.module.d.ts +10 -8
- package/dist/predictive-studio-dashboards.module.d.ts.map +1 -1
- package/dist/predictive-studio-dashboards.module.js +13 -3
- package/dist/predictive-studio-dashboards.module.js.map +1 -1
- package/package.json +64 -63
package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { OnDestroy, AfterViewInit } from '@angular/core';
|
|
24
24
|
import { Subject } from 'rxjs';
|
|
25
|
-
import { ResourceData
|
|
25
|
+
import { ResourceData } from '@memberjunction/core-entities';
|
|
26
26
|
import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
|
|
27
27
|
import { type FeaturePipelineSummary, type FeaturePipelineRunStatus } from './feature-pipeline.engine';
|
|
28
28
|
import * as i0 from "@angular/core";
|
|
@@ -42,10 +42,6 @@ export declare class FeaturePipelinesResourceComponent extends BaseResourceCompo
|
|
|
42
42
|
SearchQuery: string;
|
|
43
43
|
/** Ids of pipelines with a Run currently in flight (disables their Run button). */
|
|
44
44
|
RunningIDs: Set<string>;
|
|
45
|
-
/** Authoring dialog state. */
|
|
46
|
-
ShowEditor: boolean;
|
|
47
|
-
/** Record Process id being authored, or null for a new draft. */
|
|
48
|
-
EditingPipelineID: string | null;
|
|
49
45
|
/** Count of pipelines whose underlying Record Process is Active. */
|
|
50
46
|
get ActiveCount(): number;
|
|
51
47
|
/** Count of pipelines that have never run. */
|
|
@@ -58,10 +54,10 @@ export declare class FeaturePipelinesResourceComponent extends BaseResourceCompo
|
|
|
58
54
|
Refresh(): Promise<void>;
|
|
59
55
|
/** Apply the search filter (called on every keystroke). */
|
|
60
56
|
OnSearchChanged(): void;
|
|
61
|
-
/** Open the
|
|
57
|
+
/** Open the entity record form to create a new record process. */
|
|
62
58
|
OnNewPipeline(): void;
|
|
63
|
-
/** Open the
|
|
64
|
-
|
|
59
|
+
/** Open the entity record form in a new tab for an existing feature pipeline. */
|
|
60
|
+
OnViewPipeline(pipeline: FeaturePipelineSummary): void;
|
|
65
61
|
/**
|
|
66
62
|
* Run a feature pipeline on demand by invoking the
|
|
67
63
|
* `PredictiveStudio.RunFeaturePipeline` Remote Operation through the active
|
|
@@ -71,10 +67,6 @@ export declare class FeaturePipelinesResourceComponent extends BaseResourceCompo
|
|
|
71
67
|
OnRunPipeline(pipeline: FeaturePipelineSummary): Promise<void>;
|
|
72
68
|
/** Whether a given pipeline currently has a Run in flight. */
|
|
73
69
|
IsRunning(pipelineID: string): boolean;
|
|
74
|
-
/** Called when the editor saves — refresh and close. */
|
|
75
|
-
OnEditorSaved(_record: MJRecordProcessEntity): Promise<void>;
|
|
76
|
-
/** Called when the editor is cancelled — just close. */
|
|
77
|
-
OnEditorCancelled(): void;
|
|
78
70
|
/** Font Awesome icon for a pipeline's work type. */
|
|
79
71
|
WorkTypeIcon(workType: FeaturePipelineSummary['WorkType']): string;
|
|
80
72
|
/** CSS modifier class for a run-status pill. */
|
package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-pipelines-resource.component.d.ts","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAGL,SAAS,EACT,aAAa,EAEd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAa,MAAM,MAAM,CAAC;AAE1C,OAAO,EACL,YAAY,
|
|
1
|
+
{"version":3,"file":"feature-pipelines-resource.component.d.ts","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAGL,SAAS,EACT,aAAa,EAEd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAa,MAAM,MAAM,CAAC;AAE1C,OAAO,EACL,YAAY,EAIb,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAGrF,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC9B,MAAM,2BAA2B,CAAC;;AAWnC,qBAOa,iCACX,SAAQ,qBACR,YAAW,aAAa,EAAE,SAAS;IAEnC,OAAO,CAAC,GAAG,CAA6B;IACxC,UAAmB,iBAAiB,oBAA6B;IACjE,UAAmB,QAAQ,gBAAuB;IAM5C,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5D,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAQhE,mDAAmD;IAC5C,SAAS,UAAQ;IAExB,mDAAmD;IAC5C,YAAY,EAAE,sBAAsB,EAAE,CAAM;IAEnD,4EAA4E;IACrE,iBAAiB,EAAE,sBAAsB,EAAE,CAAM;IAExD,qEAAqE;IAC9D,WAAW,SAAM;IAExB,mFAAmF;IAC5E,UAAU,cAAqB;IAMtC,oEAAoE;IACpE,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,8CAA8C;IAC9C,IAAW,aAAa,IAAI,MAAM,CAEjC;IAED,uDAAuD;IACvD,IAAW,WAAW,IAAI,MAAM,CAE/B;IAMK,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAQtC,WAAW,IAAI,IAAI;IAUnB,gDAAgD;IACnC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC,2DAA2D;IACpD,eAAe,IAAI,IAAI;IAM9B,kEAAkE;IAC3D,aAAa,IAAI,IAAI;IAQ5B,iFAAiF;IAC1E,cAAc,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IAI7D;;;;;OAKG;IACU,aAAa,CAAC,QAAQ,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B3E,8DAA8D;IACvD,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAQ7C,oDAAoD;IAC7C,YAAY,CAAC,QAAQ,EAAE,sBAAsB,CAAC,UAAU,CAAC,GAAG,MAAM;IAkBzE,gDAAgD;IACzC,cAAc,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM;IAI/D,6CAA6C;IACtC,cAAc,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM;IAI/D,0DAA0D;IACnD,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM;IAgBzC,+EAA+E;IAC/E,OAAO,KAAK,MAAM,GAIjB;YAEa,QAAQ;IAkBtB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,eAAe;IAmCvB,OAAO,CAAC,gBAAgB;IAUxB,oFAAoF;IACpF,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,kBAAkB;yCA3Tf,iCAAiC;2CAAjC,iCAAiC;CA2X7C;AAED,mEAAmE;AACnE,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
|
package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js
CHANGED
|
@@ -28,6 +28,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
28
28
|
*/
|
|
29
29
|
import { Component, ChangeDetectorRef, inject, } from '@angular/core';
|
|
30
30
|
import { Subject, takeUntil } from 'rxjs';
|
|
31
|
+
import { CompositeKey } from '@memberjunction/core';
|
|
31
32
|
import { RegisterClass } from '@memberjunction/global';
|
|
32
33
|
import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
|
|
33
34
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
@@ -37,7 +38,6 @@ import { validateStringParam } from '../../../shared/agent-tool-validation';
|
|
|
37
38
|
import * as i0 from "@angular/core";
|
|
38
39
|
import * as i1 from "@memberjunction/ng-shared-generic";
|
|
39
40
|
import * as i2 from "@memberjunction/ng-ui-components";
|
|
40
|
-
import * as i3 from "@memberjunction/ng-record-process-studio";
|
|
41
41
|
const _forTrack0 = ($index, $item) => $item.ID;
|
|
42
42
|
function FeaturePipelinesResourceComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
43
43
|
i0.ɵɵelement(0, "mj-stat-badge", 2);
|
|
@@ -53,12 +53,12 @@ function FeaturePipelinesResourceComponent_Conditional_4_Template(rf, ctx) { if
|
|
|
53
53
|
} }
|
|
54
54
|
function FeaturePipelinesResourceComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
55
55
|
i0.ɵɵelementStart(0, "div", 11);
|
|
56
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
56
|
+
i0.ɵɵelement(1, "mj-loading", 15);
|
|
57
57
|
i0.ɵɵelementEnd();
|
|
58
58
|
} }
|
|
59
59
|
function FeaturePipelinesResourceComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
60
60
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
61
|
-
i0.ɵɵelementStart(0, "mj-empty-state",
|
|
61
|
+
i0.ɵɵelementStart(0, "mj-empty-state", 16);
|
|
62
62
|
i0.ɵɵlistener("Action", function FeaturePipelinesResourceComponent_Conditional_14_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnNewPipeline()); });
|
|
63
63
|
i0.ɵɵelementEnd();
|
|
64
64
|
} }
|
|
@@ -66,7 +66,7 @@ function FeaturePipelinesResourceComponent_Conditional_15_Template(rf, ctx) { if
|
|
|
66
66
|
i0.ɵɵelement(0, "mj-empty-state", 13);
|
|
67
67
|
} }
|
|
68
68
|
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
69
|
-
i0.ɵɵelementStart(0, "p",
|
|
69
|
+
i0.ɵɵelementStart(0, "p", 25);
|
|
70
70
|
i0.ɵɵtext(1);
|
|
71
71
|
i0.ɵɵelementEnd();
|
|
72
72
|
} if (rf & 2) {
|
|
@@ -76,7 +76,7 @@ function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_10_T
|
|
|
76
76
|
i0.ɵɵtextInterpolate(pipeline_r4.Description);
|
|
77
77
|
} }
|
|
78
78
|
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_30_Template(rf, ctx) { if (rf & 1) {
|
|
79
|
-
i0.ɵɵelementStart(0, "span",
|
|
79
|
+
i0.ɵɵelementStart(0, "span", 33);
|
|
80
80
|
i0.ɵɵtext(1);
|
|
81
81
|
i0.ɵɵelementEnd();
|
|
82
82
|
} if (rf & 2) {
|
|
@@ -85,57 +85,57 @@ function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_30_T
|
|
|
85
85
|
i0.ɵɵtextInterpolate2("\u00B7 ", pipeline_r4.LastRunSuccess, "/", pipeline_r4.LastRunProcessed, " written");
|
|
86
86
|
} }
|
|
87
87
|
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_33_Template(rf, ctx) { if (rf & 1) {
|
|
88
|
-
i0.ɵɵelement(0, "i",
|
|
88
|
+
i0.ɵɵelement(0, "i", 38);
|
|
89
89
|
i0.ɵɵtext(1, " Running\u2026 ");
|
|
90
90
|
} }
|
|
91
91
|
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
92
|
-
i0.ɵɵelement(0, "i",
|
|
92
|
+
i0.ɵɵelement(0, "i", 39);
|
|
93
93
|
i0.ɵɵtext(1, " Run ");
|
|
94
94
|
} }
|
|
95
95
|
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
96
96
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
97
|
-
i0.ɵɵelementStart(0, "div",
|
|
98
|
-
i0.ɵɵelement(2, "i",
|
|
99
|
-
i0.ɵɵelementStart(3, "div",
|
|
97
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "div", 19);
|
|
98
|
+
i0.ɵɵelement(2, "i", 20);
|
|
99
|
+
i0.ɵɵelementStart(3, "div", 21)(4, "h3", 22);
|
|
100
100
|
i0.ɵɵtext(5);
|
|
101
101
|
i0.ɵɵelementEnd();
|
|
102
|
-
i0.ɵɵelementStart(6, "span",
|
|
102
|
+
i0.ɵɵelementStart(6, "span", 23);
|
|
103
103
|
i0.ɵɵtext(7);
|
|
104
104
|
i0.ɵɵelementEnd()();
|
|
105
|
-
i0.ɵɵelementStart(8, "span",
|
|
105
|
+
i0.ɵɵelementStart(8, "span", 24);
|
|
106
106
|
i0.ɵɵtext(9);
|
|
107
107
|
i0.ɵɵelementEnd()();
|
|
108
|
-
i0.ɵɵconditionalCreate(10, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_10_Template, 2, 2, "p",
|
|
109
|
-
i0.ɵɵelementStart(11, "div",
|
|
110
|
-
i0.ɵɵelement(14, "i",
|
|
108
|
+
i0.ɵɵconditionalCreate(10, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_10_Template, 2, 2, "p", 25);
|
|
109
|
+
i0.ɵɵelementStart(11, "div", 26)(12, "div", 27)(13, "span", 28);
|
|
110
|
+
i0.ɵɵelement(14, "i", 29);
|
|
111
111
|
i0.ɵɵtext(15, " Target");
|
|
112
112
|
i0.ɵɵelementEnd();
|
|
113
|
-
i0.ɵɵelementStart(16, "span",
|
|
113
|
+
i0.ɵɵelementStart(16, "span", 30);
|
|
114
114
|
i0.ɵɵtext(17);
|
|
115
115
|
i0.ɵɵelementEnd()();
|
|
116
|
-
i0.ɵɵelementStart(18, "div",
|
|
117
|
-
i0.ɵɵelement(20, "i",
|
|
116
|
+
i0.ɵɵelementStart(18, "div", 27)(19, "span", 28);
|
|
117
|
+
i0.ɵɵelement(20, "i", 31);
|
|
118
118
|
i0.ɵɵtext(21, " Writes");
|
|
119
119
|
i0.ɵɵelementEnd();
|
|
120
|
-
i0.ɵɵelementStart(22, "span",
|
|
120
|
+
i0.ɵɵelementStart(22, "span", 30);
|
|
121
121
|
i0.ɵɵtext(23);
|
|
122
122
|
i0.ɵɵelementEnd()();
|
|
123
|
-
i0.ɵɵelementStart(24, "div",
|
|
124
|
-
i0.ɵɵelement(26, "i",
|
|
123
|
+
i0.ɵɵelementStart(24, "div", 27)(25, "span", 28);
|
|
124
|
+
i0.ɵɵelement(26, "i", 32);
|
|
125
125
|
i0.ɵɵtext(27, " Last run");
|
|
126
126
|
i0.ɵɵelementEnd();
|
|
127
|
-
i0.ɵɵelementStart(28, "span",
|
|
127
|
+
i0.ɵɵelementStart(28, "span", 30);
|
|
128
128
|
i0.ɵɵtext(29);
|
|
129
|
-
i0.ɵɵconditionalCreate(30, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_30_Template, 2, 2, "span",
|
|
129
|
+
i0.ɵɵconditionalCreate(30, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_30_Template, 2, 2, "span", 33);
|
|
130
130
|
i0.ɵɵelementEnd()()();
|
|
131
|
-
i0.ɵɵelementStart(31, "div",
|
|
131
|
+
i0.ɵɵelementStart(31, "div", 34)(32, "button", 35);
|
|
132
132
|
i0.ɵɵlistener("click", function FeaturePipelinesResourceComponent_Conditional_16_For_2_Template_button_click_32_listener() { const pipeline_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnRunPipeline(pipeline_r4)); });
|
|
133
133
|
i0.ɵɵconditionalCreate(33, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_33_Template, 2, 0)(34, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_34_Template, 2, 0);
|
|
134
134
|
i0.ɵɵelementEnd();
|
|
135
|
-
i0.ɵɵelementStart(35, "button",
|
|
136
|
-
i0.ɵɵlistener("click", function FeaturePipelinesResourceComponent_Conditional_16_For_2_Template_button_click_35_listener() { const pipeline_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.
|
|
137
|
-
i0.ɵɵelement(36, "i",
|
|
138
|
-
i0.ɵɵtext(37, "
|
|
135
|
+
i0.ɵɵelementStart(35, "button", 36);
|
|
136
|
+
i0.ɵɵlistener("click", function FeaturePipelinesResourceComponent_Conditional_16_For_2_Template_button_click_35_listener() { const pipeline_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnViewPipeline(pipeline_r4)); });
|
|
137
|
+
i0.ɵɵelement(36, "i", 37);
|
|
138
|
+
i0.ɵɵtext(37, " View ");
|
|
139
139
|
i0.ɵɵelementEnd()()();
|
|
140
140
|
} if (rf & 2) {
|
|
141
141
|
const pipeline_r4 = ctx.$implicit;
|
|
@@ -170,26 +170,13 @@ function FeaturePipelinesResourceComponent_Conditional_16_For_2_Template(rf, ctx
|
|
|
170
170
|
} }
|
|
171
171
|
function FeaturePipelinesResourceComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
172
172
|
i0.ɵɵelementStart(0, "div", 14);
|
|
173
|
-
i0.ɵɵrepeaterCreate(1, FeaturePipelinesResourceComponent_Conditional_16_For_2_Template, 38, 17, "div",
|
|
173
|
+
i0.ɵɵrepeaterCreate(1, FeaturePipelinesResourceComponent_Conditional_16_For_2_Template, 38, 17, "div", 17, _forTrack0);
|
|
174
174
|
i0.ɵɵelementEnd();
|
|
175
175
|
} if (rf & 2) {
|
|
176
176
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
177
177
|
i0.ɵɵadvance();
|
|
178
178
|
i0.ɵɵrepeater(ctx_r0.FilteredPipelines);
|
|
179
179
|
} }
|
|
180
|
-
function FeaturePipelinesResourceComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
181
|
-
const _r5 = i0.ɵɵgetCurrentView();
|
|
182
|
-
i0.ɵɵelementStart(0, "mj-dialog", 41);
|
|
183
|
-
i0.ɵɵlistener("Close", function FeaturePipelinesResourceComponent_Conditional_17_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnEditorCancelled()); });
|
|
184
|
-
i0.ɵɵelementStart(1, "mj-record-process-editor", 42);
|
|
185
|
-
i0.ɵɵlistener("Saved", function FeaturePipelinesResourceComponent_Conditional_17_Template_mj_record_process_editor_Saved_1_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnEditorSaved($event)); })("Cancelled", function FeaturePipelinesResourceComponent_Conditional_17_Template_mj_record_process_editor_Cancelled_1_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnEditorCancelled()); });
|
|
186
|
-
i0.ɵɵelementEnd()();
|
|
187
|
-
} if (rf & 2) {
|
|
188
|
-
const ctx_r0 = i0.ɵɵnextContext();
|
|
189
|
-
i0.ɵɵproperty("Visible", ctx_r0.ShowEditor)("Width", 900);
|
|
190
|
-
i0.ɵɵadvance();
|
|
191
|
-
i0.ɵɵproperty("RecordProcessID", ctx_r0.EditingPipelineID);
|
|
192
|
-
} }
|
|
193
180
|
/** Stable operation key of the Run Feature Pipeline Remote Operation. */
|
|
194
181
|
const RUN_FEATURE_PIPELINE_OP = 'PredictiveStudio.RunFeaturePipeline';
|
|
195
182
|
let FeaturePipelinesResourceComponent = class FeaturePipelinesResourceComponent extends BaseResourceComponent {
|
|
@@ -218,10 +205,6 @@ let FeaturePipelinesResourceComponent = class FeaturePipelinesResourceComponent
|
|
|
218
205
|
SearchQuery = '';
|
|
219
206
|
/** Ids of pipelines with a Run currently in flight (disables their Run button). */
|
|
220
207
|
RunningIDs = new Set();
|
|
221
|
-
/** Authoring dialog state. */
|
|
222
|
-
ShowEditor = false;
|
|
223
|
-
/** Record Process id being authored, or null for a new draft. */
|
|
224
|
-
EditingPipelineID = null;
|
|
225
208
|
// ================================================================
|
|
226
209
|
// Computed
|
|
227
210
|
// ================================================================
|
|
@@ -265,20 +248,16 @@ let FeaturePipelinesResourceComponent = class FeaturePipelinesResourceComponent
|
|
|
265
248
|
this.emitAgentContext();
|
|
266
249
|
this.cdr.detectChanges();
|
|
267
250
|
}
|
|
268
|
-
/** Open the
|
|
251
|
+
/** Open the entity record form to create a new record process. */
|
|
269
252
|
OnNewPipeline() {
|
|
270
|
-
this.
|
|
271
|
-
this.ShowEditor = true;
|
|
272
|
-
this.cdr.detectChanges();
|
|
253
|
+
this.navigationService.OpenEntityRecord('MJ: Record Processes', new CompositeKey());
|
|
273
254
|
}
|
|
274
255
|
// ================================================================
|
|
275
256
|
// Public Methods — Card Actions
|
|
276
257
|
// ================================================================
|
|
277
|
-
/** Open the
|
|
278
|
-
|
|
279
|
-
this.
|
|
280
|
-
this.ShowEditor = true;
|
|
281
|
-
this.cdr.detectChanges();
|
|
258
|
+
/** Open the entity record form in a new tab for an existing feature pipeline. */
|
|
259
|
+
OnViewPipeline(pipeline) {
|
|
260
|
+
this.navigationService.OpenEntityRecord('MJ: Record Processes', CompositeKey.FromID(pipeline.ID));
|
|
282
261
|
}
|
|
283
262
|
/**
|
|
284
263
|
* Run a feature pipeline on demand by invoking the
|
|
@@ -314,21 +293,6 @@ let FeaturePipelinesResourceComponent = class FeaturePipelinesResourceComponent
|
|
|
314
293
|
return this.RunningIDs.has(pipelineID);
|
|
315
294
|
}
|
|
316
295
|
// ================================================================
|
|
317
|
-
// Public Methods — Authoring Dialog
|
|
318
|
-
// ================================================================
|
|
319
|
-
/** Called when the editor saves — refresh and close. */
|
|
320
|
-
async OnEditorSaved(_record) {
|
|
321
|
-
this.ShowEditor = false;
|
|
322
|
-
this.EditingPipelineID = null;
|
|
323
|
-
await this.loadData(true);
|
|
324
|
-
}
|
|
325
|
-
/** Called when the editor is cancelled — just close. */
|
|
326
|
-
OnEditorCancelled() {
|
|
327
|
-
this.ShowEditor = false;
|
|
328
|
-
this.EditingPipelineID = null;
|
|
329
|
-
this.cdr.detectChanges();
|
|
330
|
-
}
|
|
331
|
-
// ================================================================
|
|
332
296
|
// Public Methods — Display Helpers
|
|
333
297
|
// ================================================================
|
|
334
298
|
/** Font Awesome icon for a pipeline's work type. */
|
|
@@ -521,7 +485,7 @@ let FeaturePipelinesResourceComponent = class FeaturePipelinesResourceComponent
|
|
|
521
485
|
},
|
|
522
486
|
{
|
|
523
487
|
Name: 'OpenFeaturePipelineEditor',
|
|
524
|
-
Description: 'Open the
|
|
488
|
+
Description: 'Open the entity record form for a feature pipeline by id or name to inspect or edit its definition.',
|
|
525
489
|
ParameterSchema: {
|
|
526
490
|
type: 'object',
|
|
527
491
|
properties: { pipeline: { type: 'string', description: 'The feature pipeline id or name' } },
|
|
@@ -531,14 +495,14 @@ let FeaturePipelinesResourceComponent = class FeaturePipelinesResourceComponent
|
|
|
531
495
|
const r = this.resolvePipelineOrFail(params['pipeline'] ?? params['name']);
|
|
532
496
|
if (!r.ok)
|
|
533
497
|
return r.result;
|
|
534
|
-
this.
|
|
498
|
+
this.OnViewPipeline(r.pipeline);
|
|
535
499
|
return { Success: true, Data: { Pipeline: r.pipeline.Name } };
|
|
536
500
|
},
|
|
537
501
|
},
|
|
538
502
|
]);
|
|
539
503
|
}
|
|
540
504
|
static ɵfac = /*@__PURE__*/ (() => { let ɵFeaturePipelinesResourceComponent_BaseFactory; return function FeaturePipelinesResourceComponent_Factory(__ngFactoryType__) { return (ɵFeaturePipelinesResourceComponent_BaseFactory || (ɵFeaturePipelinesResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(FeaturePipelinesResourceComponent)))(__ngFactoryType__ || FeaturePipelinesResourceComponent); }; })();
|
|
541
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FeaturePipelinesResourceComponent, selectors: [["app-feature-pipelines-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls:
|
|
505
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FeaturePipelinesResourceComponent, selectors: [["app-feature-pipelines-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 17, vars: 5, consts: [["Title", "Feature Pipelines", "Icon", "fa-solid fa-diagram-project", "Subtitle", "Derive feature attributes from your data and persist them back to entities"], ["meta", ""], ["Label", "last run failed", "Variant", "error", 3, "Count"], ["Label", "pipelines", 3, "Count", "Total"], ["actions", ""], [3, "Clicked", "Loading"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], ["toolbar", ""], ["Placeholder", "Search by name, entity, or attribute\u2026", 3, "ValueChange", "Value"], [3, "Flex"], [1, "fp-loading"], ["Icon", "fa-solid fa-diagram-project", "Title", "No feature pipelines yet", "Message", "A Feature Pipeline derives an attribute per record (e.g. an LLM summary or score) and writes it back to your data \u2014 reusable analytics, independent of any model.", "ActionText", "New Pipeline", "ActionIcon", "fa-solid fa-plus"], ["Variant", "no-results", "Icon", "fa-solid fa-magnifying-glass", "Title", "No matching pipelines", "Message", "No feature pipelines match your search."], [1, "fp-grid"], ["text", "Loading feature pipelines\u2026", "size", "medium"], ["Icon", "fa-solid fa-diagram-project", "Title", "No feature pipelines yet", "Message", "A Feature Pipeline derives an attribute per record (e.g. an LLM summary or score) and writes it back to your data \u2014 reusable analytics, independent of any model.", "ActionText", "New Pipeline", "ActionIcon", "fa-solid fa-plus", 3, "Action"], [1, "fp-card", 3, "fp-card--disabled"], [1, "fp-card"], [1, "fp-card__head"], [1, "fp-card__icon"], [1, "fp-card__title"], [3, "title"], [1, "fp-card__worktype"], [1, "fp-status"], [1, "fp-card__desc", 3, "title"], [1, "fp-card__meta"], [1, "fp-meta-row"], [1, "fp-meta-row__k"], [1, "fa-solid", "fa-table"], [1, "fp-meta-row__v"], [1, "fa-solid", "fa-pen-to-square"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "fp-meta-row__sub"], [1, "fp-card__actions"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-eye"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-play"]], template: function FeaturePipelinesResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
542
506
|
i0.ɵɵelementStart(0, "mj-page-layout")(1, "mj-page-header", 0)(2, "div", 1);
|
|
543
507
|
i0.ɵɵconditionalCreate(3, FeaturePipelinesResourceComponent_Conditional_3_Template, 1, 1, "mj-stat-badge", 2)(4, FeaturePipelinesResourceComponent_Conditional_4_Template, 1, 2, "mj-stat-badge", 3);
|
|
544
508
|
i0.ɵɵelementEnd();
|
|
@@ -556,7 +520,6 @@ let FeaturePipelinesResourceComponent = class FeaturePipelinesResourceComponent
|
|
|
556
520
|
i0.ɵɵelementStart(12, "mj-page-body", 10);
|
|
557
521
|
i0.ɵɵconditionalCreate(13, FeaturePipelinesResourceComponent_Conditional_13_Template, 2, 0, "div", 11)(14, FeaturePipelinesResourceComponent_Conditional_14_Template, 1, 0, "mj-empty-state", 12)(15, FeaturePipelinesResourceComponent_Conditional_15_Template, 1, 0, "mj-empty-state", 13)(16, FeaturePipelinesResourceComponent_Conditional_16_Template, 3, 0, "div", 14);
|
|
558
522
|
i0.ɵɵelementEnd()();
|
|
559
|
-
i0.ɵɵconditionalCreate(17, FeaturePipelinesResourceComponent_Conditional_17_Template, 2, 3, "mj-dialog", 15);
|
|
560
523
|
} if (rf & 2) {
|
|
561
524
|
i0.ɵɵadvance(3);
|
|
562
525
|
i0.ɵɵconditional(ctx.FailedCount > 0 ? 3 : 4);
|
|
@@ -568,9 +531,7 @@ let FeaturePipelinesResourceComponent = class FeaturePipelinesResourceComponent
|
|
|
568
531
|
i0.ɵɵproperty("Flex", true);
|
|
569
532
|
i0.ɵɵadvance();
|
|
570
533
|
i0.ɵɵconditional(ctx.IsLoading ? 13 : ctx.AllPipelines.length === 0 ? 14 : ctx.FilteredPipelines.length === 0 ? 15 : 16);
|
|
571
|
-
|
|
572
|
-
i0.ɵɵconditional(ctx.ShowEditor ? 17 : -1);
|
|
573
|
-
} }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective, i2.MJPageHeaderComponent, i2.MJPageLayoutComponent, i2.MJPageBodyComponent, i2.MJPageSearchComponent, i2.MJStatBadgeComponent, i2.MJRefreshButtonComponent, i2.MJDialogComponent, i2.MJEmptyStateComponent, i3.RecordProcessEditorComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n.fp-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 240px;\n width: 100%;\n}\n\n.fp-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n gap: 16px;\n padding: 4px;\n align-content: start;\n}\n\n.fp-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg, 10px);\n background: var(--mj-bg-surface-card);\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.fp-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.fp-card--disabled[_ngcontent-%COMP%] {\n opacity: 0.65;\n}\n\n.fp-card__head[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.fp-card__icon[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--mj-radius-md, 8px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.fp-card__title[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.fp-card__title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.fp-card__worktype[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n}\n\n.fp-card__desc[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n line-height: 1.4;\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.fp-card__meta[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 0;\n border-top: 1px solid var(--mj-border-subtle);\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.fp-meta-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n font-size: 13px;\n}\n\n.fp-meta-row__k[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n color: var(--mj-text-muted);\n}\n\n.fp-meta-row__k[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 14px;\n margin-right: 4px;\n}\n\n.fp-meta-row__v[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n text-align: right;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.fp-meta-row__sub[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.fp-card__actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: auto;\n}\n\n\n.fp-status[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n align-self: flex-start;\n padding: 2px 10px;\n border-radius: var(--mj-radius-full, 999px);\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.fp-status.status--never[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.fp-status.status--running[_ngcontent-%COMP%] {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n}\n\n.fp-status.status--completed[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.fp-status.status--failed[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.fp-status.status--cancelled[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}"] });
|
|
534
|
+
} }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective, i2.MJPageHeaderComponent, i2.MJPageLayoutComponent, i2.MJPageBodyComponent, i2.MJPageSearchComponent, i2.MJStatBadgeComponent, i2.MJRefreshButtonComponent, i2.MJEmptyStateComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n.fp-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 240px;\n width: 100%;\n}\n\n.fp-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n gap: 16px;\n padding: 4px;\n align-content: start;\n}\n\n.fp-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg, 10px);\n background: var(--mj-bg-surface-card);\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.fp-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.fp-card--disabled[_ngcontent-%COMP%] {\n opacity: 0.65;\n}\n\n.fp-card__head[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.fp-card__icon[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--mj-radius-md, 8px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.fp-card__title[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.fp-card__title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.fp-card__worktype[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n}\n\n.fp-card__desc[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n line-height: 1.4;\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.fp-card__meta[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 0;\n border-top: 1px solid var(--mj-border-subtle);\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.fp-meta-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n font-size: 13px;\n}\n\n.fp-meta-row__k[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n color: var(--mj-text-muted);\n}\n\n.fp-meta-row__k[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 14px;\n margin-right: 4px;\n}\n\n.fp-meta-row__v[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n text-align: right;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.fp-meta-row__sub[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.fp-card__actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: auto;\n}\n\n\n.fp-status[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n align-self: flex-start;\n padding: 2px 10px;\n border-radius: var(--mj-radius-full, 999px);\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.fp-status.status--never[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.fp-status.status--running[_ngcontent-%COMP%] {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n}\n\n.fp-status.status--completed[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.fp-status.status--failed[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.fp-status.status--cancelled[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}"] });
|
|
574
535
|
};
|
|
575
536
|
FeaturePipelinesResourceComponent = __decorate([
|
|
576
537
|
RegisterClass(BaseResourceComponent, 'FeaturePipelinesResource')
|
|
@@ -578,7 +539,7 @@ FeaturePipelinesResourceComponent = __decorate([
|
|
|
578
539
|
export { FeaturePipelinesResourceComponent };
|
|
579
540
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FeaturePipelinesResourceComponent, [{
|
|
580
541
|
type: Component,
|
|
581
|
-
args: [{ standalone: false, selector: 'app-feature-pipelines-resource', template: "<mj-page-layout>\n <mj-page-header\n Title=\"Feature Pipelines\"\n Icon=\"fa-solid fa-diagram-project\"\n Subtitle=\"Derive feature attributes from your data and persist them back to entities\">\n <div meta>\n @if (FailedCount > 0) {\n <mj-stat-badge [Count]=\"FailedCount\" Label=\"last run failed\" Variant=\"error\"></mj-stat-badge>\n } @else {\n <mj-stat-badge\n [Count]=\"FilteredPipelines.length\"\n [Total]=\"AllPipelines.length\"\n Label=\"pipelines\">\n </mj-stat-badge>\n }\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"Refresh()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewPipeline()\">\n <i class=\"fa-solid fa-plus\"></i> New Pipeline\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n [Value]=\"SearchQuery\"\n Placeholder=\"Search by name, entity, or attribute\u2026\"\n (ValueChange)=\"SearchQuery = $event; OnSearchChanged()\">\n </mj-page-search>\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\">\n @if (IsLoading) {\n <div class=\"fp-loading\">\n <mj-loading text=\"Loading feature pipelines\u2026\" size=\"medium\"></mj-loading>\n </div>\n } @else if (AllPipelines.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n Title=\"No feature pipelines yet\"\n Message=\"A Feature Pipeline derives an attribute per record (e.g. an LLM summary or score) and writes it back to your data \u2014 reusable analytics, independent of any model.\"\n ActionText=\"New Pipeline\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnNewPipeline()\">\n </mj-empty-state>\n } @else if (FilteredPipelines.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No matching pipelines\"\n Message=\"No feature pipelines match your search.\">\n </mj-empty-state>\n } @else {\n <div class=\"fp-grid\">\n @for (pipeline of FilteredPipelines; track pipeline.ID) {\n <div class=\"fp-card\" [class.fp-card--disabled]=\"pipeline.Status !== 'Active'\">\n <div class=\"fp-card__head\">\n <i class=\"fp-card__icon\" [class]=\"WorkTypeIcon(pipeline.WorkType)\"></i>\n <div class=\"fp-card__title\">\n <h3 [title]=\"pipeline.Name\">{{ pipeline.Name }}</h3>\n <span class=\"fp-card__worktype\">{{ pipeline.WorkType }}</span>\n </div>\n <span class=\"fp-status\" [class]=\"RunStatusClass(pipeline.LastRunStatus)\">\n {{ RunStatusLabel(pipeline.LastRunStatus) }}\n </span>\n </div>\n\n @if (pipeline.Description) {\n <p class=\"fp-card__desc\" [title]=\"pipeline.Description\">{{ pipeline.Description }}</p>\n }\n\n <div class=\"fp-card__meta\">\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-table\"></i> Target</span>\n <span class=\"fp-meta-row__v\">{{ pipeline.TargetEntity }}</span>\n </div>\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-pen-to-square\"></i> Writes</span>\n <span class=\"fp-meta-row__v\">{{ pipeline.OutputAttribute || '\u2014' }}</span>\n </div>\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-clock-rotate-left\"></i> Last run</span>\n <span class=\"fp-meta-row__v\">\n {{ TimeAgo(pipeline.LastRunAt) }}\n @if (pipeline.LastRunProcessed != null) {\n <span class=\"fp-meta-row__sub\">\u00B7 {{ pipeline.LastRunSuccess }}/{{ pipeline.LastRunProcessed }} written</span>\n }\n </span>\n </div>\n </div>\n\n <div class=\"fp-card__actions\">\n <button\n mjButton\n variant=\"primary\"\n size=\"sm\"\n [disabled]=\"!pipeline.OnDemandEnabled || pipeline.Status !== 'Active' || IsRunning(pipeline.ID)\"\n (click)=\"OnRunPipeline(pipeline)\">\n @if (IsRunning(pipeline.ID)) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Running\u2026\n } @else {\n <i class=\"fa-solid fa-play\"></i> Run\n }\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"
|
|
542
|
+
args: [{ standalone: false, selector: 'app-feature-pipelines-resource', template: "<mj-page-layout>\n <mj-page-header\n Title=\"Feature Pipelines\"\n Icon=\"fa-solid fa-diagram-project\"\n Subtitle=\"Derive feature attributes from your data and persist them back to entities\">\n <div meta>\n @if (FailedCount > 0) {\n <mj-stat-badge [Count]=\"FailedCount\" Label=\"last run failed\" Variant=\"error\"></mj-stat-badge>\n } @else {\n <mj-stat-badge\n [Count]=\"FilteredPipelines.length\"\n [Total]=\"AllPipelines.length\"\n Label=\"pipelines\">\n </mj-stat-badge>\n }\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"Refresh()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewPipeline()\">\n <i class=\"fa-solid fa-plus\"></i> New Pipeline\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n [Value]=\"SearchQuery\"\n Placeholder=\"Search by name, entity, or attribute\u2026\"\n (ValueChange)=\"SearchQuery = $event; OnSearchChanged()\">\n </mj-page-search>\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\">\n @if (IsLoading) {\n <div class=\"fp-loading\">\n <mj-loading text=\"Loading feature pipelines\u2026\" size=\"medium\"></mj-loading>\n </div>\n } @else if (AllPipelines.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n Title=\"No feature pipelines yet\"\n Message=\"A Feature Pipeline derives an attribute per record (e.g. an LLM summary or score) and writes it back to your data \u2014 reusable analytics, independent of any model.\"\n ActionText=\"New Pipeline\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnNewPipeline()\">\n </mj-empty-state>\n } @else if (FilteredPipelines.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No matching pipelines\"\n Message=\"No feature pipelines match your search.\">\n </mj-empty-state>\n } @else {\n <div class=\"fp-grid\">\n @for (pipeline of FilteredPipelines; track pipeline.ID) {\n <div class=\"fp-card\" [class.fp-card--disabled]=\"pipeline.Status !== 'Active'\">\n <div class=\"fp-card__head\">\n <i class=\"fp-card__icon\" [class]=\"WorkTypeIcon(pipeline.WorkType)\"></i>\n <div class=\"fp-card__title\">\n <h3 [title]=\"pipeline.Name\">{{ pipeline.Name }}</h3>\n <span class=\"fp-card__worktype\">{{ pipeline.WorkType }}</span>\n </div>\n <span class=\"fp-status\" [class]=\"RunStatusClass(pipeline.LastRunStatus)\">\n {{ RunStatusLabel(pipeline.LastRunStatus) }}\n </span>\n </div>\n\n @if (pipeline.Description) {\n <p class=\"fp-card__desc\" [title]=\"pipeline.Description\">{{ pipeline.Description }}</p>\n }\n\n <div class=\"fp-card__meta\">\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-table\"></i> Target</span>\n <span class=\"fp-meta-row__v\">{{ pipeline.TargetEntity }}</span>\n </div>\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-pen-to-square\"></i> Writes</span>\n <span class=\"fp-meta-row__v\">{{ pipeline.OutputAttribute || '\u2014' }}</span>\n </div>\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-clock-rotate-left\"></i> Last run</span>\n <span class=\"fp-meta-row__v\">\n {{ TimeAgo(pipeline.LastRunAt) }}\n @if (pipeline.LastRunProcessed != null) {\n <span class=\"fp-meta-row__sub\">\u00B7 {{ pipeline.LastRunSuccess }}/{{ pipeline.LastRunProcessed }} written</span>\n }\n </span>\n </div>\n </div>\n\n <div class=\"fp-card__actions\">\n <button\n mjButton\n variant=\"primary\"\n size=\"sm\"\n [disabled]=\"!pipeline.OnDemandEnabled || pipeline.Status !== 'Active' || IsRunning(pipeline.ID)\"\n (click)=\"OnRunPipeline(pipeline)\">\n @if (IsRunning(pipeline.ID)) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Running\u2026\n } @else {\n <i class=\"fa-solid fa-play\"></i> Run\n }\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"OnViewPipeline(pipeline)\">\n <i class=\"fa-solid fa-eye\"></i> View\n </button>\n </div>\n </div>\n }\n </div>\n }\n </mj-page-body>\n</mj-page-layout>\n", styles: ["/**\n * Feature Pipelines (Knowledge Hub) \u2014 card-grid layout.\n * All colors use semantic design tokens (dark-mode + white-label safe).\n *\n * NOTE: this package builds with bare `ngc` (no Sass step) \u2014 component styles\n * are embedded RAW into the compiled JS. Keep this file FLAT, plain CSS.\n * Sass nesting / BEM selector concatenation would be silently dropped by the\n * browser and the rules would be DEAD. See .github/scripts/check-ngc-scss.sh\n * (CI gate) and MemberJunction/MJ#3105.\n */\n\n.fp-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 240px;\n width: 100%;\n}\n\n.fp-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n gap: 16px;\n padding: 4px;\n align-content: start;\n}\n\n.fp-card {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg, 10px);\n background: var(--mj-bg-surface-card);\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.fp-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.fp-card--disabled {\n opacity: 0.65;\n}\n\n.fp-card__head {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.fp-card__icon {\n flex: 0 0 auto;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--mj-radius-md, 8px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.fp-card__title {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.fp-card__title h3 {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.fp-card__worktype {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n}\n\n.fp-card__desc {\n margin: 0;\n font-size: 13px;\n line-height: 1.4;\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.fp-card__meta {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 0;\n border-top: 1px solid var(--mj-border-subtle);\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.fp-meta-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n font-size: 13px;\n}\n\n.fp-meta-row__k {\n flex: 0 0 auto;\n color: var(--mj-text-muted);\n}\n\n.fp-meta-row__k i {\n width: 14px;\n margin-right: 4px;\n}\n\n.fp-meta-row__v {\n flex: 1 1 auto;\n text-align: right;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.fp-meta-row__sub {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.fp-card__actions {\n display: flex;\n gap: 8px;\n margin-top: auto;\n}\n\n/* Run-status pill \u2014 semantic status tokens */\n.fp-status {\n flex: 0 0 auto;\n align-self: flex-start;\n padding: 2px 10px;\n border-radius: var(--mj-radius-full, 999px);\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.fp-status.status--never {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.fp-status.status--running {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n}\n\n.fp-status.status--completed {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.fp-status.status--failed {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.fp-status.status--cancelled {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n"] }]
|
|
582
543
|
}], null, null); })();
|
|
583
544
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FeaturePipelinesResourceComponent, { className: "FeaturePipelinesResourceComponent", filePath: "src/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.ts", lineNumber: 65 }); })();
|
|
584
545
|
/** Tree-shaking prevention — keeps the component in the bundle. */
|
package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-pipelines-resource.component.js","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.ts","../../../../src/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Knowledge Hub — Feature Pipelines dashboard tab.\n *\n * Full-page resource component listing the **Feature Pipelines** (Predictive\n * Studio SP6 / `plans/predictive-studio.md` §5.4). A Feature Pipeline has no\n * dedicated entity: it IS an `MJ: Record Processes` row categorized into the\n * seeded \"Feature Pipeline\" category (Infer / Action / Agent + a write-back\n * `OutputMapping`). This surface makes them first-class + discoverable +\n * monitorable inside Knowledge Hub:\n *\n * - lists the feature-pipeline Record Processes (from {@link FeaturePipelineEngine}),\n * - shows each one's target entity, written attribute, and last-run / freshness,\n * - offers **Run** (invokes the existing `PredictiveStudio.RunFeaturePipeline`\n * Remote Operation via the provider's `RouteOperation` seam — the same\n * hardened Record Set Processing run path), and\n * - an **authoring** entry that opens the reusable `mj-record-process-editor`\n * (from `@memberjunction/ng-record-process-studio`) in a dialog — we do NOT\n * rebuild the authoring surface.\n *\n * Registered as `BaseResourceComponent` driver `FeaturePipelinesResource`; wired\n * into the Knowledge Hub application's nav via metadata (`DriverClass`).\n */\n\nimport {\n Component,\n ChangeDetectorRef,\n OnDestroy,\n AfterViewInit,\n inject,\n} from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\nimport type { RemoteOpResult, IRemoteOperationProvider } from '@memberjunction/core';\nimport {\n ResourceData,\n MJRecordProcessEntity,\n type PredictiveStudioRunFeaturePipelineInput,\n type PredictiveStudioRunFeaturePipelineOutput,\n} from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\n\nimport {\n FeaturePipelineEngine,\n type FeaturePipelineSummary,\n type FeaturePipelineRunStatus,\n} from './feature-pipeline.engine';\nimport {\n buildFeaturePipelinesAgentContext,\n resolvePipeline,\n buildPipelineNotFoundError,\n} from './feature-pipelines-agent-context';\nimport { validateStringParam, AgentToolResult } from '../../../shared/agent-tool-validation';\n\n/** Stable operation key of the Run Feature Pipeline Remote Operation. */\nconst RUN_FEATURE_PIPELINE_OP = 'PredictiveStudio.RunFeaturePipeline';\n\n@RegisterClass(BaseResourceComponent, 'FeaturePipelinesResource')\n@Component({\n standalone: false,\n selector: 'app-feature-pipelines-resource',\n templateUrl: './feature-pipelines-resource.component.html',\n styleUrls: ['./feature-pipelines-resource.component.css'],\n})\nexport class FeaturePipelinesResourceComponent\n extends BaseResourceComponent\n implements AfterViewInit, OnDestroy\n{\n private cdr = inject(ChangeDetectorRef);\n protected override navigationService = inject(NavigationService);\n protected override destroy$ = new Subject<void>();\n\n // ================================================================\n // Resource overrides\n // ================================================================\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'Feature Pipelines';\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-diagram-project';\n }\n\n // ================================================================\n // State\n // ================================================================\n\n /** True while the engine is loading its caches. */\n public IsLoading = true;\n\n /** All feature-pipeline summaries (unfiltered). */\n public AllPipelines: FeaturePipelineSummary[] = [];\n\n /** Pipelines after the search filter is applied (what the cards render). */\n public FilteredPipelines: FeaturePipelineSummary[] = [];\n\n /** Free-text search over name / target entity / output attribute. */\n public SearchQuery = '';\n\n /** Ids of pipelines with a Run currently in flight (disables their Run button). */\n public RunningIDs = new Set<string>();\n\n /** Authoring dialog state. */\n public ShowEditor = false;\n\n /** Record Process id being authored, or null for a new draft. */\n public EditingPipelineID: string | null = null;\n\n // ================================================================\n // Computed\n // ================================================================\n\n /** Count of pipelines whose underlying Record Process is Active. */\n public get ActiveCount(): number {\n return this.AllPipelines.filter((p) => p.Status === 'Active').length;\n }\n\n /** Count of pipelines that have never run. */\n public get NeverRunCount(): number {\n return this.AllPipelines.filter((p) => p.LastRunStatus === 'Never').length;\n }\n\n /** Count of pipelines whose most recent run failed. */\n public get FailedCount(): number {\n return this.AllPipelines.filter((p) => p.LastRunStatus === 'Failed').length;\n }\n\n // ================================================================\n // Lifecycle\n // ================================================================\n\n async ngAfterViewInit(): Promise<void> {\n await this.loadData();\n this.subscribeToEngine();\n this.emitAgentContext();\n this.registerAgentTools();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ================================================================\n // Public Methods — Toolbar\n // ================================================================\n\n /** Reload the engine caches from the server. */\n public async Refresh(): Promise<void> {\n await this.loadData(true);\n }\n\n /** Apply the search filter (called on every keystroke). */\n public OnSearchChanged(): void {\n this.applyFilter();\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n /** Open the authoring editor for a brand-new feature pipeline draft. */\n public OnNewPipeline(): void {\n this.EditingPipelineID = null;\n this.ShowEditor = true;\n this.cdr.detectChanges();\n }\n\n // ================================================================\n // Public Methods — Card Actions\n // ================================================================\n\n /** Open the authoring editor for an existing feature pipeline. */\n public OnEditPipeline(pipeline: FeaturePipelineSummary): void {\n this.EditingPipelineID = pipeline.ID;\n this.ShowEditor = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Run a feature pipeline on demand by invoking the\n * `PredictiveStudio.RunFeaturePipeline` Remote Operation through the active\n * provider. The op delegates to the Record Set Processing substrate — the same\n * batching/resume/audit path the rest of the platform uses.\n */\n public async OnRunPipeline(pipeline: FeaturePipelineSummary): Promise<void> {\n if (this.RunningIDs.has(pipeline.ID)) return;\n\n this.RunningIDs.add(pipeline.ID);\n this.cdr.detectChanges();\n\n try {\n const input: PredictiveStudioRunFeaturePipelineInput = { featurePipelineID: pipeline.ID };\n // RouteOperation lives on IRemoteOperationProvider, which every concrete\n // provider (the browser's GraphQLDataProvider here) implements via ProviderBase.\n // The narrowing cast is the documented \"power-tool seam\" entry point.\n const opProvider = this.ProviderToUse as unknown as IRemoteOperationProvider;\n const result = await opProvider.RouteOperation<\n PredictiveStudioRunFeaturePipelineInput,\n PredictiveStudioRunFeaturePipelineOutput\n >(RUN_FEATURE_PIPELINE_OP, input, { provider: this.ProviderToUse });\n\n this.notifyRunResult(pipeline, result);\n } catch (error) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Failed to run \"${pipeline.Name}\": ${error instanceof Error ? error.message : String(error)}`,\n 'error',\n 5000,\n );\n } finally {\n this.RunningIDs.delete(pipeline.ID);\n // Refresh so the card reflects the new run / freshness.\n await this.loadData(true);\n }\n }\n\n /** Whether a given pipeline currently has a Run in flight. */\n public IsRunning(pipelineID: string): boolean {\n return this.RunningIDs.has(pipelineID);\n }\n\n // ================================================================\n // Public Methods — Authoring Dialog\n // ================================================================\n\n /** Called when the editor saves — refresh and close. */\n public async OnEditorSaved(_record: MJRecordProcessEntity): Promise<void> {\n this.ShowEditor = false;\n this.EditingPipelineID = null;\n await this.loadData(true);\n }\n\n /** Called when the editor is cancelled — just close. */\n public OnEditorCancelled(): void {\n this.ShowEditor = false;\n this.EditingPipelineID = null;\n this.cdr.detectChanges();\n }\n\n // ================================================================\n // Public Methods — Display Helpers\n // ================================================================\n\n /** Font Awesome icon for a pipeline's work type. */\n public WorkTypeIcon(workType: FeaturePipelineSummary['WorkType']): string {\n switch (workType) {\n case 'Infer':\n return 'fa-solid fa-wand-magic-sparkles';\n case 'Agent':\n return 'fa-solid fa-robot';\n case 'Action':\n return 'fa-solid fa-bolt';\n case 'FieldRules':\n return 'fa-solid fa-list-check';\n case 'ML Model':\n return 'fa-solid fa-brain';\n default:\n // Keeps the function total against future CodeGen-added work types.\n return 'fa-solid fa-gear';\n }\n }\n\n /** CSS modifier class for a run-status pill. */\n public RunStatusClass(status: FeaturePipelineRunStatus): string {\n return `status--${status.toLowerCase()}`;\n }\n\n /** Human-readable label for a run status. */\n public RunStatusLabel(status: FeaturePipelineRunStatus): string {\n return status === 'Never' ? 'Never run' : status;\n }\n\n /** Relative \"x ago\" string for the last-run timestamp. */\n public TimeAgo(date: Date | null): string {\n if (!date) return 'Never';\n const diffMs = Date.now() - new Date(date).getTime();\n const minutes = Math.floor(diffMs / 60000);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n if (days > 0) return `${days}d ago`;\n if (hours > 0) return `${hours}h ago`;\n if (minutes > 0) return `${minutes}m ago`;\n return 'Just now';\n }\n\n // ================================================================\n // Private Methods\n // ================================================================\n\n /** The engine instance scoped to the active provider (multi-provider safe). */\n private get engine(): FeaturePipelineEngine {\n return <FeaturePipelineEngine>(\n FeaturePipelineEngine.GetProviderInstance(this.ProviderToUse, FeaturePipelineEngine)\n );\n }\n\n private async loadData(forceRefresh = false): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n try {\n const p = this.ProviderToUse;\n await this.engine.Config(forceRefresh, p.CurrentUser, p);\n this.AllPipelines = this.engine.GetSummaries();\n this.applyFilter();\n } catch (error) {\n console.error('[FeaturePipelinesResource] Error loading data:', error);\n this.AllPipelines = [];\n this.FilteredPipelines = [];\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Re-derive the summaries whenever the engine's cached Record Processes or\n * Process Runs change (save / delete / remote-invalidate elsewhere) — reactivity\n * for free from the BaseEngine streams.\n */\n private subscribeToEngine(): void {\n this.engine.Pipelines$.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.AllPipelines = this.engine.GetSummaries();\n this.applyFilter();\n this.emitAgentContext();\n this.cdr.detectChanges();\n });\n }\n\n private applyFilter(): void {\n const q = this.SearchQuery.trim().toLowerCase();\n if (!q) {\n this.FilteredPipelines = this.AllPipelines;\n return;\n }\n this.FilteredPipelines = this.AllPipelines.filter(\n (p) =>\n p.Name.toLowerCase().includes(q) ||\n p.TargetEntity.toLowerCase().includes(q) ||\n (p.OutputAttribute ?? '').toLowerCase().includes(q),\n );\n }\n\n private notifyRunResult(\n pipeline: FeaturePipelineSummary,\n result: RemoteOpResult<PredictiveStudioRunFeaturePipelineOutput>,\n ): void {\n if (result.Success && result.Output) {\n const out = result.Output;\n MJNotificationService.Instance.CreateSimpleNotification(\n `\"${pipeline.Name}\" finished: ${out.written} written, ${out.processed} processed, ${out.error} error(s).`,\n out.error > 0 ? 'warning' : 'success',\n 5000,\n );\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n `\"${pipeline.Name}\" did not complete: ${result.ErrorMessage ?? 'unknown error'}`,\n 'error',\n 5000,\n );\n }\n }\n\n // ---- Agent context + client tools (required for every dashboard) ----\n //\n // 🔒 SAFETY BOUNDARY (Feature Pipelines surface)\n // ----------------------------------------------\n // EXPOSED to the agent: idempotent refresh, read-only search/filter, selection,\n // opening a pipeline's authoring editor (UI — no auto-save), and the existing\n // on-demand RUN (RunFeaturePipeline). Running a feature pipeline is intentionally\n // exposed: it is an idempotent, hardened Record-Set-Processing pass that derives\n // and writes feature values back via the pipeline's own OutputMapping — the same\n // run path the platform uses everywhere, with no agent-supplied parameters.\n //\n // NEVER EXPOSED: there is no agent tool that saves/deletes a pipeline definition\n // or its OutputMapping (authoring is a deliberate UI action via the editor\n // dialog). The agent may *open* the editor, never commit it.\n\n private emitAgentContext(): void {\n this.navigationService.SetAgentContext(this, buildFeaturePipelinesAgentContext({\n AllPipelines: this.AllPipelines,\n FilteredPipelines: this.FilteredPipelines,\n SearchQuery: this.SearchQuery,\n RunningIDs: this.RunningIDs,\n IsLoading: this.IsLoading,\n }));\n }\n\n /** Resolve a pipeline reference (id/name/contains) or return a tolerant failure. */\n private resolvePipelineOrFail(\n raw: unknown,\n ): { ok: true; pipeline: FeaturePipelineSummary } | { ok: false; result: AgentToolResult } {\n const v = validateStringParam(raw, 'pipeline');\n if (!v.ok) return { ok: false, result: v.result };\n const match = resolvePipeline(v.value, this.AllPipelines);\n if (!match) {\n return {\n ok: false,\n result: {\n Success: false,\n ErrorMessage: buildPipelineNotFoundError(v.value, this.AllPipelines.map((p) => p.Name)),\n },\n };\n }\n return { ok: true, pipeline: match };\n }\n\n private registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'RunFeaturePipeline',\n Description:\n 'Run a Feature Pipeline on demand by its id or name. Derives + persists feature values back to the target entity via the pipeline OutputMapping (idempotent Record-Set-Processing pass; no agent-supplied parameters).',\n ParameterSchema: {\n type: 'object',\n properties: { pipeline: { type: 'string', description: 'The feature pipeline id or name' } },\n required: ['pipeline'],\n },\n Handler: async (params: Record<string, unknown>) => {\n const r = this.resolvePipelineOrFail(params['pipeline'] ?? params['name']);\n if (!r.ok) return r.result;\n if (!r.pipeline.OnDemandEnabled) {\n return { Success: false, ErrorMessage: `\"${r.pipeline.Name}\" is not enabled for on-demand runs.` };\n }\n await this.OnRunPipeline(r.pipeline);\n return { Success: true, Data: { Pipeline: r.pipeline.Name } };\n },\n },\n {\n Name: 'SearchFeaturePipelines',\n Description: 'Filter the feature pipeline list by a search term (name / target entity / attribute). Pass empty to clear. Read-only.',\n ParameterSchema: {\n type: 'object',\n properties: { query: { type: 'string' } },\n required: ['query'],\n },\n Handler: async (params: Record<string, unknown>) => {\n const v = validateStringParam(params['query'], 'query');\n if (!v.ok) return v.result;\n this.SearchQuery = v.value;\n this.OnSearchChanged();\n return { Success: true, Data: { FilteredCount: this.FilteredPipelines.length } };\n },\n },\n {\n Name: 'RefreshFeaturePipelines',\n Description: 'Reload the feature pipelines and their latest run/freshness from the server. Idempotent.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n await this.Refresh();\n this.emitAgentContext();\n return { Success: true, Data: { PipelineCount: this.AllPipelines.length } };\n },\n },\n {\n Name: 'OpenFeaturePipelineEditor',\n Description: 'Open the authoring editor for a feature pipeline by id or name (UI dialog — does NOT auto-save). Use to inspect or edit a pipeline definition.',\n ParameterSchema: {\n type: 'object',\n properties: { pipeline: { type: 'string', description: 'The feature pipeline id or name' } },\n required: ['pipeline'],\n },\n Handler: async (params: Record<string, unknown>) => {\n const r = this.resolvePipelineOrFail(params['pipeline'] ?? params['name']);\n if (!r.ok) return r.result;\n this.OnEditPipeline(r.pipeline);\n return { Success: true, Data: { Pipeline: r.pipeline.Name } };\n },\n },\n ]);\n }\n}\n\n/** Tree-shaking prevention — keeps the component in the bundle. */\nexport function LoadFeaturePipelinesResource(): void {\n // Prevents tree-shaking of the component.\n}\n","<mj-page-layout>\n <mj-page-header\n Title=\"Feature Pipelines\"\n Icon=\"fa-solid fa-diagram-project\"\n Subtitle=\"Derive feature attributes from your data and persist them back to entities\">\n <div meta>\n @if (FailedCount > 0) {\n <mj-stat-badge [Count]=\"FailedCount\" Label=\"last run failed\" Variant=\"error\"></mj-stat-badge>\n } @else {\n <mj-stat-badge\n [Count]=\"FilteredPipelines.length\"\n [Total]=\"AllPipelines.length\"\n Label=\"pipelines\">\n </mj-stat-badge>\n }\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"Refresh()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewPipeline()\">\n <i class=\"fa-solid fa-plus\"></i> New Pipeline\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n [Value]=\"SearchQuery\"\n Placeholder=\"Search by name, entity, or attribute…\"\n (ValueChange)=\"SearchQuery = $event; OnSearchChanged()\">\n </mj-page-search>\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\">\n @if (IsLoading) {\n <div class=\"fp-loading\">\n <mj-loading text=\"Loading feature pipelines…\" size=\"medium\"></mj-loading>\n </div>\n } @else if (AllPipelines.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n Title=\"No feature pipelines yet\"\n Message=\"A Feature Pipeline derives an attribute per record (e.g. an LLM summary or score) and writes it back to your data — reusable analytics, independent of any model.\"\n ActionText=\"New Pipeline\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnNewPipeline()\">\n </mj-empty-state>\n } @else if (FilteredPipelines.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No matching pipelines\"\n Message=\"No feature pipelines match your search.\">\n </mj-empty-state>\n } @else {\n <div class=\"fp-grid\">\n @for (pipeline of FilteredPipelines; track pipeline.ID) {\n <div class=\"fp-card\" [class.fp-card--disabled]=\"pipeline.Status !== 'Active'\">\n <div class=\"fp-card__head\">\n <i class=\"fp-card__icon\" [class]=\"WorkTypeIcon(pipeline.WorkType)\"></i>\n <div class=\"fp-card__title\">\n <h3 [title]=\"pipeline.Name\">{{ pipeline.Name }}</h3>\n <span class=\"fp-card__worktype\">{{ pipeline.WorkType }}</span>\n </div>\n <span class=\"fp-status\" [class]=\"RunStatusClass(pipeline.LastRunStatus)\">\n {{ RunStatusLabel(pipeline.LastRunStatus) }}\n </span>\n </div>\n\n @if (pipeline.Description) {\n <p class=\"fp-card__desc\" [title]=\"pipeline.Description\">{{ pipeline.Description }}</p>\n }\n\n <div class=\"fp-card__meta\">\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-table\"></i> Target</span>\n <span class=\"fp-meta-row__v\">{{ pipeline.TargetEntity }}</span>\n </div>\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-pen-to-square\"></i> Writes</span>\n <span class=\"fp-meta-row__v\">{{ pipeline.OutputAttribute || '—' }}</span>\n </div>\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-clock-rotate-left\"></i> Last run</span>\n <span class=\"fp-meta-row__v\">\n {{ TimeAgo(pipeline.LastRunAt) }}\n @if (pipeline.LastRunProcessed != null) {\n <span class=\"fp-meta-row__sub\">· {{ pipeline.LastRunSuccess }}/{{ pipeline.LastRunProcessed }} written</span>\n }\n </span>\n </div>\n </div>\n\n <div class=\"fp-card__actions\">\n <button\n mjButton\n variant=\"primary\"\n size=\"sm\"\n [disabled]=\"!pipeline.OnDemandEnabled || pipeline.Status !== 'Active' || IsRunning(pipeline.ID)\"\n (click)=\"OnRunPipeline(pipeline)\">\n @if (IsRunning(pipeline.ID)) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Running…\n } @else {\n <i class=\"fa-solid fa-play\"></i> Run\n }\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"OnEditPipeline(pipeline)\">\n <i class=\"fa-solid fa-sliders\"></i> Edit\n </button>\n </div>\n </div>\n }\n </div>\n }\n </mj-page-body>\n</mj-page-layout>\n\n@if (ShowEditor) {\n <mj-dialog [Visible]=\"ShowEditor\" Title=\"Feature Pipeline\" [Width]=\"900\" (Close)=\"OnEditorCancelled()\">\n <mj-record-process-editor\n [RecordProcessID]=\"EditingPipelineID\"\n (Saved)=\"OnEditorSaved($event)\"\n (Cancelled)=\"OnEditorCancelled()\">\n </mj-record-process-editor>\n </mj-dialog>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"feature-pipelines-resource.component.js","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.ts","../../../../src/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Knowledge Hub — Feature Pipelines dashboard tab.\n *\n * Full-page resource component listing the **Feature Pipelines** (Predictive\n * Studio SP6 / `plans/predictive-studio.md` §5.4). A Feature Pipeline has no\n * dedicated entity: it IS an `MJ: Record Processes` row categorized into the\n * seeded \"Feature Pipeline\" category (Infer / Action / Agent + a write-back\n * `OutputMapping`). This surface makes them first-class + discoverable +\n * monitorable inside Knowledge Hub:\n *\n * - lists the feature-pipeline Record Processes (from {@link FeaturePipelineEngine}),\n * - shows each one's target entity, written attribute, and last-run / freshness,\n * - offers **Run** (invokes the existing `PredictiveStudio.RunFeaturePipeline`\n * Remote Operation via the provider's `RouteOperation` seam — the same\n * hardened Record Set Processing run path), and\n * - an **authoring** entry that opens the reusable `mj-record-process-editor`\n * (from `@memberjunction/ng-record-process-studio`) in a dialog — we do NOT\n * rebuild the authoring surface.\n *\n * Registered as `BaseResourceComponent` driver `FeaturePipelinesResource`; wired\n * into the Knowledge Hub application's nav via metadata (`DriverClass`).\n */\n\nimport {\n Component,\n ChangeDetectorRef,\n OnDestroy,\n AfterViewInit,\n inject,\n} from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\nimport { CompositeKey, type RemoteOpResult, type IRemoteOperationProvider } from '@memberjunction/core';\nimport {\n ResourceData,\n MJRecordProcessEntity,\n type PredictiveStudioRunFeaturePipelineInput,\n type PredictiveStudioRunFeaturePipelineOutput,\n} from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\n\nimport {\n FeaturePipelineEngine,\n type FeaturePipelineSummary,\n type FeaturePipelineRunStatus,\n} from './feature-pipeline.engine';\nimport {\n buildFeaturePipelinesAgentContext,\n resolvePipeline,\n buildPipelineNotFoundError,\n} from './feature-pipelines-agent-context';\nimport { validateStringParam, AgentToolResult } from '../../../shared/agent-tool-validation';\n\n/** Stable operation key of the Run Feature Pipeline Remote Operation. */\nconst RUN_FEATURE_PIPELINE_OP = 'PredictiveStudio.RunFeaturePipeline';\n\n@RegisterClass(BaseResourceComponent, 'FeaturePipelinesResource')\n@Component({\n standalone: false,\n selector: 'app-feature-pipelines-resource',\n templateUrl: './feature-pipelines-resource.component.html',\n styleUrls: ['./feature-pipelines-resource.component.css'],\n})\nexport class FeaturePipelinesResourceComponent\n extends BaseResourceComponent\n implements AfterViewInit, OnDestroy\n{\n private cdr = inject(ChangeDetectorRef);\n protected override navigationService = inject(NavigationService);\n protected override destroy$ = new Subject<void>();\n\n // ================================================================\n // Resource overrides\n // ================================================================\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'Feature Pipelines';\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-diagram-project';\n }\n\n // ================================================================\n // State\n // ================================================================\n\n /** True while the engine is loading its caches. */\n public IsLoading = true;\n\n /** All feature-pipeline summaries (unfiltered). */\n public AllPipelines: FeaturePipelineSummary[] = [];\n\n /** Pipelines after the search filter is applied (what the cards render). */\n public FilteredPipelines: FeaturePipelineSummary[] = [];\n\n /** Free-text search over name / target entity / output attribute. */\n public SearchQuery = '';\n\n /** Ids of pipelines with a Run currently in flight (disables their Run button). */\n public RunningIDs = new Set<string>();\n\n // ================================================================\n // Computed\n // ================================================================\n\n /** Count of pipelines whose underlying Record Process is Active. */\n public get ActiveCount(): number {\n return this.AllPipelines.filter((p) => p.Status === 'Active').length;\n }\n\n /** Count of pipelines that have never run. */\n public get NeverRunCount(): number {\n return this.AllPipelines.filter((p) => p.LastRunStatus === 'Never').length;\n }\n\n /** Count of pipelines whose most recent run failed. */\n public get FailedCount(): number {\n return this.AllPipelines.filter((p) => p.LastRunStatus === 'Failed').length;\n }\n\n // ================================================================\n // Lifecycle\n // ================================================================\n\n async ngAfterViewInit(): Promise<void> {\n await this.loadData();\n this.subscribeToEngine();\n this.emitAgentContext();\n this.registerAgentTools();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ================================================================\n // Public Methods — Toolbar\n // ================================================================\n\n /** Reload the engine caches from the server. */\n public async Refresh(): Promise<void> {\n await this.loadData(true);\n }\n\n /** Apply the search filter (called on every keystroke). */\n public OnSearchChanged(): void {\n this.applyFilter();\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n /** Open the entity record form to create a new record process. */\n public OnNewPipeline(): void {\n this.navigationService.OpenEntityRecord('MJ: Record Processes', new CompositeKey());\n }\n\n // ================================================================\n // Public Methods — Card Actions\n // ================================================================\n\n /** Open the entity record form in a new tab for an existing feature pipeline. */\n public OnViewPipeline(pipeline: FeaturePipelineSummary): void {\n this.navigationService.OpenEntityRecord('MJ: Record Processes', CompositeKey.FromID(pipeline.ID));\n }\n\n /**\n * Run a feature pipeline on demand by invoking the\n * `PredictiveStudio.RunFeaturePipeline` Remote Operation through the active\n * provider. The op delegates to the Record Set Processing substrate — the same\n * batching/resume/audit path the rest of the platform uses.\n */\n public async OnRunPipeline(pipeline: FeaturePipelineSummary): Promise<void> {\n if (this.RunningIDs.has(pipeline.ID)) return;\n\n this.RunningIDs.add(pipeline.ID);\n this.cdr.detectChanges();\n\n try {\n const input: PredictiveStudioRunFeaturePipelineInput = { featurePipelineID: pipeline.ID };\n // RouteOperation lives on IRemoteOperationProvider, which every concrete\n // provider (the browser's GraphQLDataProvider here) implements via ProviderBase.\n // The narrowing cast is the documented \"power-tool seam\" entry point.\n const opProvider = this.ProviderToUse as unknown as IRemoteOperationProvider;\n const result = await opProvider.RouteOperation<\n PredictiveStudioRunFeaturePipelineInput,\n PredictiveStudioRunFeaturePipelineOutput\n >(RUN_FEATURE_PIPELINE_OP, input, { provider: this.ProviderToUse });\n\n this.notifyRunResult(pipeline, result);\n } catch (error) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Failed to run \"${pipeline.Name}\": ${error instanceof Error ? error.message : String(error)}`,\n 'error',\n 5000,\n );\n } finally {\n this.RunningIDs.delete(pipeline.ID);\n // Refresh so the card reflects the new run / freshness.\n await this.loadData(true);\n }\n }\n\n /** Whether a given pipeline currently has a Run in flight. */\n public IsRunning(pipelineID: string): boolean {\n return this.RunningIDs.has(pipelineID);\n }\n\n // ================================================================\n // Public Methods — Display Helpers\n // ================================================================\n\n /** Font Awesome icon for a pipeline's work type. */\n public WorkTypeIcon(workType: FeaturePipelineSummary['WorkType']): string {\n switch (workType) {\n case 'Infer':\n return 'fa-solid fa-wand-magic-sparkles';\n case 'Agent':\n return 'fa-solid fa-robot';\n case 'Action':\n return 'fa-solid fa-bolt';\n case 'FieldRules':\n return 'fa-solid fa-list-check';\n case 'ML Model':\n return 'fa-solid fa-brain';\n default:\n // Keeps the function total against future CodeGen-added work types.\n return 'fa-solid fa-gear';\n }\n }\n\n /** CSS modifier class for a run-status pill. */\n public RunStatusClass(status: FeaturePipelineRunStatus): string {\n return `status--${status.toLowerCase()}`;\n }\n\n /** Human-readable label for a run status. */\n public RunStatusLabel(status: FeaturePipelineRunStatus): string {\n return status === 'Never' ? 'Never run' : status;\n }\n\n /** Relative \"x ago\" string for the last-run timestamp. */\n public TimeAgo(date: Date | null): string {\n if (!date) return 'Never';\n const diffMs = Date.now() - new Date(date).getTime();\n const minutes = Math.floor(diffMs / 60000);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n if (days > 0) return `${days}d ago`;\n if (hours > 0) return `${hours}h ago`;\n if (minutes > 0) return `${minutes}m ago`;\n return 'Just now';\n }\n\n // ================================================================\n // Private Methods\n // ================================================================\n\n /** The engine instance scoped to the active provider (multi-provider safe). */\n private get engine(): FeaturePipelineEngine {\n return <FeaturePipelineEngine>(\n FeaturePipelineEngine.GetProviderInstance(this.ProviderToUse, FeaturePipelineEngine)\n );\n }\n\n private async loadData(forceRefresh = false): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n try {\n const p = this.ProviderToUse;\n await this.engine.Config(forceRefresh, p.CurrentUser, p);\n this.AllPipelines = this.engine.GetSummaries();\n this.applyFilter();\n } catch (error) {\n console.error('[FeaturePipelinesResource] Error loading data:', error);\n this.AllPipelines = [];\n this.FilteredPipelines = [];\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Re-derive the summaries whenever the engine's cached Record Processes or\n * Process Runs change (save / delete / remote-invalidate elsewhere) — reactivity\n * for free from the BaseEngine streams.\n */\n private subscribeToEngine(): void {\n this.engine.Pipelines$.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.AllPipelines = this.engine.GetSummaries();\n this.applyFilter();\n this.emitAgentContext();\n this.cdr.detectChanges();\n });\n }\n\n private applyFilter(): void {\n const q = this.SearchQuery.trim().toLowerCase();\n if (!q) {\n this.FilteredPipelines = this.AllPipelines;\n return;\n }\n this.FilteredPipelines = this.AllPipelines.filter(\n (p) =>\n p.Name.toLowerCase().includes(q) ||\n p.TargetEntity.toLowerCase().includes(q) ||\n (p.OutputAttribute ?? '').toLowerCase().includes(q),\n );\n }\n\n private notifyRunResult(\n pipeline: FeaturePipelineSummary,\n result: RemoteOpResult<PredictiveStudioRunFeaturePipelineOutput>,\n ): void {\n if (result.Success && result.Output) {\n const out = result.Output;\n MJNotificationService.Instance.CreateSimpleNotification(\n `\"${pipeline.Name}\" finished: ${out.written} written, ${out.processed} processed, ${out.error} error(s).`,\n out.error > 0 ? 'warning' : 'success',\n 5000,\n );\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n `\"${pipeline.Name}\" did not complete: ${result.ErrorMessage ?? 'unknown error'}`,\n 'error',\n 5000,\n );\n }\n }\n\n // ---- Agent context + client tools (required for every dashboard) ----\n //\n // 🔒 SAFETY BOUNDARY (Feature Pipelines surface)\n // ----------------------------------------------\n // EXPOSED to the agent: idempotent refresh, read-only search/filter, selection,\n // opening a pipeline's authoring editor (UI — no auto-save), and the existing\n // on-demand RUN (RunFeaturePipeline). Running a feature pipeline is intentionally\n // exposed: it is an idempotent, hardened Record-Set-Processing pass that derives\n // and writes feature values back via the pipeline's own OutputMapping — the same\n // run path the platform uses everywhere, with no agent-supplied parameters.\n //\n // NEVER EXPOSED: there is no agent tool that saves/deletes a pipeline definition\n // or its OutputMapping (authoring is a deliberate UI action via the editor\n // dialog). The agent may *open* the editor, never commit it.\n\n private emitAgentContext(): void {\n this.navigationService.SetAgentContext(this, buildFeaturePipelinesAgentContext({\n AllPipelines: this.AllPipelines,\n FilteredPipelines: this.FilteredPipelines,\n SearchQuery: this.SearchQuery,\n RunningIDs: this.RunningIDs,\n IsLoading: this.IsLoading,\n }));\n }\n\n /** Resolve a pipeline reference (id/name/contains) or return a tolerant failure. */\n private resolvePipelineOrFail(\n raw: unknown,\n ): { ok: true; pipeline: FeaturePipelineSummary } | { ok: false; result: AgentToolResult } {\n const v = validateStringParam(raw, 'pipeline');\n if (!v.ok) return { ok: false, result: v.result };\n const match = resolvePipeline(v.value, this.AllPipelines);\n if (!match) {\n return {\n ok: false,\n result: {\n Success: false,\n ErrorMessage: buildPipelineNotFoundError(v.value, this.AllPipelines.map((p) => p.Name)),\n },\n };\n }\n return { ok: true, pipeline: match };\n }\n\n private registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'RunFeaturePipeline',\n Description:\n 'Run a Feature Pipeline on demand by its id or name. Derives + persists feature values back to the target entity via the pipeline OutputMapping (idempotent Record-Set-Processing pass; no agent-supplied parameters).',\n ParameterSchema: {\n type: 'object',\n properties: { pipeline: { type: 'string', description: 'The feature pipeline id or name' } },\n required: ['pipeline'],\n },\n Handler: async (params: Record<string, unknown>) => {\n const r = this.resolvePipelineOrFail(params['pipeline'] ?? params['name']);\n if (!r.ok) return r.result;\n if (!r.pipeline.OnDemandEnabled) {\n return { Success: false, ErrorMessage: `\"${r.pipeline.Name}\" is not enabled for on-demand runs.` };\n }\n await this.OnRunPipeline(r.pipeline);\n return { Success: true, Data: { Pipeline: r.pipeline.Name } };\n },\n },\n {\n Name: 'SearchFeaturePipelines',\n Description: 'Filter the feature pipeline list by a search term (name / target entity / attribute). Pass empty to clear. Read-only.',\n ParameterSchema: {\n type: 'object',\n properties: { query: { type: 'string' } },\n required: ['query'],\n },\n Handler: async (params: Record<string, unknown>) => {\n const v = validateStringParam(params['query'], 'query');\n if (!v.ok) return v.result;\n this.SearchQuery = v.value;\n this.OnSearchChanged();\n return { Success: true, Data: { FilteredCount: this.FilteredPipelines.length } };\n },\n },\n {\n Name: 'RefreshFeaturePipelines',\n Description: 'Reload the feature pipelines and their latest run/freshness from the server. Idempotent.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n await this.Refresh();\n this.emitAgentContext();\n return { Success: true, Data: { PipelineCount: this.AllPipelines.length } };\n },\n },\n {\n Name: 'OpenFeaturePipelineEditor',\n Description: 'Open the entity record form for a feature pipeline by id or name to inspect or edit its definition.',\n ParameterSchema: {\n type: 'object',\n properties: { pipeline: { type: 'string', description: 'The feature pipeline id or name' } },\n required: ['pipeline'],\n },\n Handler: async (params: Record<string, unknown>) => {\n const r = this.resolvePipelineOrFail(params['pipeline'] ?? params['name']);\n if (!r.ok) return r.result;\n this.OnViewPipeline(r.pipeline);\n return { Success: true, Data: { Pipeline: r.pipeline.Name } };\n },\n },\n ]);\n }\n}\n\n/** Tree-shaking prevention — keeps the component in the bundle. */\nexport function LoadFeaturePipelinesResource(): void {\n // Prevents tree-shaking of the component.\n}\n","<mj-page-layout>\n <mj-page-header\n Title=\"Feature Pipelines\"\n Icon=\"fa-solid fa-diagram-project\"\n Subtitle=\"Derive feature attributes from your data and persist them back to entities\">\n <div meta>\n @if (FailedCount > 0) {\n <mj-stat-badge [Count]=\"FailedCount\" Label=\"last run failed\" Variant=\"error\"></mj-stat-badge>\n } @else {\n <mj-stat-badge\n [Count]=\"FilteredPipelines.length\"\n [Total]=\"AllPipelines.length\"\n Label=\"pipelines\">\n </mj-stat-badge>\n }\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"Refresh()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewPipeline()\">\n <i class=\"fa-solid fa-plus\"></i> New Pipeline\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n [Value]=\"SearchQuery\"\n Placeholder=\"Search by name, entity, or attribute…\"\n (ValueChange)=\"SearchQuery = $event; OnSearchChanged()\">\n </mj-page-search>\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\">\n @if (IsLoading) {\n <div class=\"fp-loading\">\n <mj-loading text=\"Loading feature pipelines…\" size=\"medium\"></mj-loading>\n </div>\n } @else if (AllPipelines.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n Title=\"No feature pipelines yet\"\n Message=\"A Feature Pipeline derives an attribute per record (e.g. an LLM summary or score) and writes it back to your data — reusable analytics, independent of any model.\"\n ActionText=\"New Pipeline\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnNewPipeline()\">\n </mj-empty-state>\n } @else if (FilteredPipelines.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No matching pipelines\"\n Message=\"No feature pipelines match your search.\">\n </mj-empty-state>\n } @else {\n <div class=\"fp-grid\">\n @for (pipeline of FilteredPipelines; track pipeline.ID) {\n <div class=\"fp-card\" [class.fp-card--disabled]=\"pipeline.Status !== 'Active'\">\n <div class=\"fp-card__head\">\n <i class=\"fp-card__icon\" [class]=\"WorkTypeIcon(pipeline.WorkType)\"></i>\n <div class=\"fp-card__title\">\n <h3 [title]=\"pipeline.Name\">{{ pipeline.Name }}</h3>\n <span class=\"fp-card__worktype\">{{ pipeline.WorkType }}</span>\n </div>\n <span class=\"fp-status\" [class]=\"RunStatusClass(pipeline.LastRunStatus)\">\n {{ RunStatusLabel(pipeline.LastRunStatus) }}\n </span>\n </div>\n\n @if (pipeline.Description) {\n <p class=\"fp-card__desc\" [title]=\"pipeline.Description\">{{ pipeline.Description }}</p>\n }\n\n <div class=\"fp-card__meta\">\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-table\"></i> Target</span>\n <span class=\"fp-meta-row__v\">{{ pipeline.TargetEntity }}</span>\n </div>\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-pen-to-square\"></i> Writes</span>\n <span class=\"fp-meta-row__v\">{{ pipeline.OutputAttribute || '—' }}</span>\n </div>\n <div class=\"fp-meta-row\">\n <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-clock-rotate-left\"></i> Last run</span>\n <span class=\"fp-meta-row__v\">\n {{ TimeAgo(pipeline.LastRunAt) }}\n @if (pipeline.LastRunProcessed != null) {\n <span class=\"fp-meta-row__sub\">· {{ pipeline.LastRunSuccess }}/{{ pipeline.LastRunProcessed }} written</span>\n }\n </span>\n </div>\n </div>\n\n <div class=\"fp-card__actions\">\n <button\n mjButton\n variant=\"primary\"\n size=\"sm\"\n [disabled]=\"!pipeline.OnDemandEnabled || pipeline.Status !== 'Active' || IsRunning(pipeline.ID)\"\n (click)=\"OnRunPipeline(pipeline)\">\n @if (IsRunning(pipeline.ID)) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Running…\n } @else {\n <i class=\"fa-solid fa-play\"></i> Run\n }\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"OnViewPipeline(pipeline)\">\n <i class=\"fa-solid fa-eye\"></i> View\n </button>\n </div>\n </div>\n }\n </div>\n }\n </mj-page-body>\n</mj-page-layout>\n"]}
|