@memberjunction/ng-dashboards 5.26.0 → 5.27.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/analytics/agent-runs/agent-run-analysis.component.d.ts +96 -0
- package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.d.ts.map +1 -0
- package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js +710 -0
- package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js.map +1 -0
- package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts +52 -0
- package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -0
- package/dist/AI/components/analytics/ai-analytics-resource.component.js +356 -0
- package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -0
- package/dist/AI/components/analytics/analytics-filter-bar.component.d.ts +52 -0
- package/dist/AI/components/analytics/analytics-filter-bar.component.d.ts.map +1 -0
- package/dist/AI/components/analytics/analytics-filter-bar.component.js +306 -0
- package/dist/AI/components/analytics/analytics-filter-bar.component.js.map +1 -0
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +81 -0
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -0
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +744 -0
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -0
- package/dist/AI/components/analytics/error-analysis/error-analysis.component.d.ts +61 -0
- package/dist/AI/components/analytics/error-analysis/error-analysis.component.d.ts.map +1 -0
- package/dist/AI/components/analytics/error-analysis/error-analysis.component.js +490 -0
- package/dist/AI/components/analytics/error-analysis/error-analysis.component.js.map +1 -0
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts +77 -0
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -0
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +673 -0
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -0
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +65 -0
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -0
- package/dist/AI/components/analytics/model-performance/model-performance.component.js +537 -0
- package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -0
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts +131 -0
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -0
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +1030 -0
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -0
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts +78 -0
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -0
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +569 -0
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -0
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +4 -14
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/overview/ai-overview-hub.component.d.ts +58 -0
- package/dist/AI/components/overview/ai-overview-hub.component.d.ts.map +1 -0
- package/dist/AI/components/overview/ai-overview-hub.component.js +315 -0
- package/dist/AI/components/overview/ai-overview-hub.component.js.map +1 -0
- package/dist/AI/components/prompts/prompt-management.component.js +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/index.d.ts +11 -0
- package/dist/AI/index.d.ts.map +1 -1
- package/dist/AI/index.js +13 -0
- package/dist/AI/index.js.map +1 -1
- package/dist/AI/interfaces/analytics-preferences.interface.d.ts +50 -0
- package/dist/AI/interfaces/analytics-preferences.interface.d.ts.map +1 -0
- package/dist/AI/interfaces/analytics-preferences.interface.js +9 -0
- package/dist/AI/interfaces/analytics-preferences.interface.js.map +1 -0
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +2 -2
- package/dist/MCP/index.d.ts +1 -0
- package/dist/MCP/index.d.ts.map +1 -1
- package/dist/MCP/index.js +2 -0
- package/dist/MCP/index.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.d.ts +1 -0
- package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +5 -4
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/MCP/mcp-resource.component.d.ts +6 -5
- package/dist/MCP/mcp-resource.component.d.ts.map +1 -1
- package/dist/MCP/mcp-resource.component.js +7 -8
- package/dist/MCP/mcp-resource.component.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +27 -17
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +66 -3
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +1 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +48 -48
- package/dist/__tests__/analytics-resource.test.d.ts +0 -2
- package/dist/__tests__/analytics-resource.test.d.ts.map +0 -1
- package/dist/__tests__/analytics-resource.test.js +0 -181
- package/dist/__tests__/analytics-resource.test.js.map +0 -1
- package/dist/__tests__/dashboards.test.d.ts +0 -2
- package/dist/__tests__/dashboards.test.d.ts.map +0 -1
- package/dist/__tests__/dashboards.test.js +0 -40
- package/dist/__tests__/dashboards.test.js.map +0 -1
- package/dist/__tests__/integration-data-service.test.d.ts +0 -2
- package/dist/__tests__/integration-data-service.test.d.ts.map +0 -1
- package/dist/__tests__/integration-data-service.test.js +0 -132
- package/dist/__tests__/integration-data-service.test.js.map +0 -1
- package/dist/__tests__/mapping-validation.test.d.ts +0 -2
- package/dist/__tests__/mapping-validation.test.d.ts.map +0 -1
- package/dist/__tests__/mapping-validation.test.js +0 -170
- package/dist/__tests__/mapping-validation.test.js.map +0 -1
- package/dist/__tests__/scheduling.test.d.ts +0 -2
- package/dist/__tests__/scheduling.test.d.ts.map +0 -1
- package/dist/__tests__/scheduling.test.js +0 -205
- package/dist/__tests__/scheduling.test.js.map +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Reusable filter bar for AI Analytics dashboard sections.
|
|
3
|
+
*
|
|
4
|
+
* Provides time-range chips, model/agent/prompt/status dropdowns
|
|
5
|
+
* (using mj-dropdown), a compare toggle, and an optional export button.
|
|
6
|
+
* Each section shows/hides filters via boolean inputs.
|
|
7
|
+
*/
|
|
8
|
+
import { EventEmitter, OnInit } from '@angular/core';
|
|
9
|
+
import { GlobalFilterState } from '../../interfaces/analytics-preferences.interface';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
interface FilterOption {
|
|
12
|
+
text: string;
|
|
13
|
+
value: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export declare class AnalyticsFilterBarComponent implements OnInit {
|
|
17
|
+
TimeRange: string;
|
|
18
|
+
TimeRangeOptions: string[];
|
|
19
|
+
ShowModelFilter: boolean;
|
|
20
|
+
ShowAgentFilter: boolean;
|
|
21
|
+
ShowPromptFilter: boolean;
|
|
22
|
+
ShowStatusFilter: boolean;
|
|
23
|
+
ShowCompareToggle: boolean;
|
|
24
|
+
ShowExportButton: boolean;
|
|
25
|
+
Filters: GlobalFilterState;
|
|
26
|
+
TimeRangeChange: EventEmitter<string>;
|
|
27
|
+
FiltersChange: EventEmitter<GlobalFilterState>;
|
|
28
|
+
CompareToggled: EventEmitter<boolean>;
|
|
29
|
+
ExportClicked: EventEmitter<void>;
|
|
30
|
+
ModelOptions: FilterOption[];
|
|
31
|
+
AgentOptions: FilterOption[];
|
|
32
|
+
PromptOptions: FilterOption[];
|
|
33
|
+
StatusOptions: FilterOption[];
|
|
34
|
+
/** Default items shown when nothing is selected (the "All X" option) */
|
|
35
|
+
modelDefaultItem: FilterOption;
|
|
36
|
+
agentDefaultItem: FilterOption;
|
|
37
|
+
promptDefaultItem: FilterOption;
|
|
38
|
+
statusDefaultItem: FilterOption;
|
|
39
|
+
compareActive: boolean;
|
|
40
|
+
ngOnInit(): void;
|
|
41
|
+
OnTimeRangeSelect(range: string): void;
|
|
42
|
+
OnModelChange(event: unknown): void;
|
|
43
|
+
OnAgentChange(event: unknown): void;
|
|
44
|
+
OnPromptChange(event: unknown): void;
|
|
45
|
+
OnStatusChange(event: unknown): void;
|
|
46
|
+
ToggleCompare(): void;
|
|
47
|
+
private BuildOptions;
|
|
48
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AnalyticsFilterBarComponent, never>;
|
|
49
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AnalyticsFilterBarComponent, "app-analytics-filter-bar", never, { "TimeRange": { "alias": "TimeRange"; "required": false; }; "TimeRangeOptions": { "alias": "TimeRangeOptions"; "required": false; }; "ShowModelFilter": { "alias": "ShowModelFilter"; "required": false; }; "ShowAgentFilter": { "alias": "ShowAgentFilter"; "required": false; }; "ShowPromptFilter": { "alias": "ShowPromptFilter"; "required": false; }; "ShowStatusFilter": { "alias": "ShowStatusFilter"; "required": false; }; "ShowCompareToggle": { "alias": "ShowCompareToggle"; "required": false; }; "ShowExportButton": { "alias": "ShowExportButton"; "required": false; }; "Filters": { "alias": "Filters"; "required": false; }; }, { "TimeRangeChange": "TimeRangeChange"; "FiltersChange": "FiltersChange"; "CompareToggled": "CompareToggled"; "ExportClicked": "ExportClicked"; }, never, never, false, never>;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=analytics-filter-bar.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-filter-bar.component.d.ts","sourceRoot":"","sources":["../../../../src/AI/components/analytics/analytics-filter-bar.component.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;;AAErF,UAAU,YAAY;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,qBAkNa,2BAA4B,YAAW,MAAM;IAC7C,SAAS,SAAS;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAoC;IAC9D,eAAe,UAAQ;IACvB,eAAe,UAAQ;IACvB,gBAAgB,UAAQ;IACxB,gBAAgB,UAAQ;IACxB,iBAAiB,UAAQ;IACzB,gBAAgB,UAAS;IACzB,OAAO,EAAE,iBAAiB,CAAyD;IAElF,eAAe,uBAA8B;IAC7C,aAAa,kCAAyC;IACtD,cAAc,wBAA+B;IAC7C,aAAa,qBAA4B;IAE5C,YAAY,EAAE,YAAY,EAAE,CAAM;IAClC,YAAY,EAAE,YAAY,EAAE,CAAM;IAClC,aAAa,EAAE,YAAY,EAAE,CAAM;IACnC,aAAa,EAAE,YAAY,EAAE,CAMlC;IAEF,wEAAwE;IACjE,gBAAgB,EAAE,YAAY,CAAqC;IACnE,gBAAgB,EAAE,YAAY,CAAqC;IACnE,iBAAiB,EAAE,YAAY,CAAsC;IACrE,iBAAiB,EAAE,YAAY,CAAuC;IAEtE,aAAa,UAAS;IAE7B,QAAQ,IAAI,IAAI;IAIT,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKtC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAMnC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAMnC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAMpC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAMpC,aAAa,IAAI,IAAI;IAK5B,OAAO,CAAC,YAAY;yCAzEX,2BAA2B;2CAA3B,2BAA2B;CAyFvC"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Reusable filter bar for AI Analytics dashboard sections.
|
|
3
|
+
*
|
|
4
|
+
* Provides time-range chips, model/agent/prompt/status dropdowns
|
|
5
|
+
* (using mj-dropdown), a compare toggle, and an optional export button.
|
|
6
|
+
* Each section shows/hides filters via boolean inputs.
|
|
7
|
+
*/
|
|
8
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
9
|
+
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
import * as i1 from "@memberjunction/ng-ui-components";
|
|
12
|
+
function AnalyticsFilterBarComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
13
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
14
|
+
i0.ɵɵelementStart(0, "mj-dropdown", 12);
|
|
15
|
+
i0.ɵɵlistener("ValueChange", function AnalyticsFilterBarComponent_Conditional_5_Template_mj_dropdown_ValueChange_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnModelChange($event)); });
|
|
16
|
+
i0.ɵɵelementEnd();
|
|
17
|
+
} if (rf & 2) {
|
|
18
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
19
|
+
i0.ɵɵproperty("Data", ctx_r1.ModelOptions)("ValuePrimitive", true)("DefaultItem", ctx_r1.modelDefaultItem)("Filterable", ctx_r1.ModelOptions.length > 10);
|
|
20
|
+
} }
|
|
21
|
+
function AnalyticsFilterBarComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
22
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
23
|
+
i0.ɵɵelementStart(0, "mj-dropdown", 13);
|
|
24
|
+
i0.ɵɵlistener("ValueChange", function AnalyticsFilterBarComponent_Conditional_6_Template_mj_dropdown_ValueChange_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnAgentChange($event)); });
|
|
25
|
+
i0.ɵɵelementEnd();
|
|
26
|
+
} if (rf & 2) {
|
|
27
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
28
|
+
i0.ɵɵproperty("Data", ctx_r1.AgentOptions)("ValuePrimitive", true)("DefaultItem", ctx_r1.agentDefaultItem)("Filterable", ctx_r1.AgentOptions.length > 10);
|
|
29
|
+
} }
|
|
30
|
+
function AnalyticsFilterBarComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
31
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
32
|
+
i0.ɵɵelementStart(0, "mj-dropdown", 14);
|
|
33
|
+
i0.ɵɵlistener("ValueChange", function AnalyticsFilterBarComponent_Conditional_7_Template_mj_dropdown_ValueChange_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnPromptChange($event)); });
|
|
34
|
+
i0.ɵɵelementEnd();
|
|
35
|
+
} if (rf & 2) {
|
|
36
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
37
|
+
i0.ɵɵproperty("Data", ctx_r1.PromptOptions)("ValuePrimitive", true)("DefaultItem", ctx_r1.promptDefaultItem)("Filterable", ctx_r1.PromptOptions.length > 10);
|
|
38
|
+
} }
|
|
39
|
+
function AnalyticsFilterBarComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
40
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
41
|
+
i0.ɵɵelementStart(0, "mj-dropdown", 15);
|
|
42
|
+
i0.ɵɵlistener("ValueChange", function AnalyticsFilterBarComponent_Conditional_8_Template_mj_dropdown_ValueChange_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnStatusChange($event)); });
|
|
43
|
+
i0.ɵɵelementEnd();
|
|
44
|
+
} if (rf & 2) {
|
|
45
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
46
|
+
i0.ɵɵproperty("Data", ctx_r1.StatusOptions)("ValuePrimitive", true)("DefaultItem", ctx_r1.statusDefaultItem);
|
|
47
|
+
} }
|
|
48
|
+
function AnalyticsFilterBarComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
49
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
50
|
+
i0.ɵɵelementStart(0, "button", 16);
|
|
51
|
+
i0.ɵɵlistener("click", function AnalyticsFilterBarComponent_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleCompare()); });
|
|
52
|
+
i0.ɵɵelement(1, "i", 17);
|
|
53
|
+
i0.ɵɵtext(2, " Compare ");
|
|
54
|
+
i0.ɵɵelementEnd();
|
|
55
|
+
} if (rf & 2) {
|
|
56
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
57
|
+
i0.ɵɵclassProp("active", ctx_r1.compareActive);
|
|
58
|
+
} }
|
|
59
|
+
function AnalyticsFilterBarComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
60
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
61
|
+
i0.ɵɵelementStart(0, "button", 18);
|
|
62
|
+
i0.ɵɵlistener("click", function AnalyticsFilterBarComponent_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ExportClicked.emit()); });
|
|
63
|
+
i0.ɵɵelement(1, "i", 19);
|
|
64
|
+
i0.ɵɵtext(2, " Export ");
|
|
65
|
+
i0.ɵɵelementEnd();
|
|
66
|
+
} }
|
|
67
|
+
function AnalyticsFilterBarComponent_For_13_Template(rf, ctx) { if (rf & 1) {
|
|
68
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
69
|
+
i0.ɵɵelementStart(0, "button", 20);
|
|
70
|
+
i0.ɵɵlistener("click", function AnalyticsFilterBarComponent_For_13_Template_button_click_0_listener() { const option_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnTimeRangeSelect(option_r9)); });
|
|
71
|
+
i0.ɵɵtext(1);
|
|
72
|
+
i0.ɵɵelementEnd();
|
|
73
|
+
} if (rf & 2) {
|
|
74
|
+
const option_r9 = ctx.$implicit;
|
|
75
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
76
|
+
i0.ɵɵclassProp("active", ctx_r1.TimeRange === option_r9);
|
|
77
|
+
i0.ɵɵadvance();
|
|
78
|
+
i0.ɵɵtextInterpolate1(" ", option_r9, " ");
|
|
79
|
+
} }
|
|
80
|
+
export class AnalyticsFilterBarComponent {
|
|
81
|
+
TimeRange = '24h';
|
|
82
|
+
TimeRangeOptions = ['1h', '6h', '24h', '7d', '30d'];
|
|
83
|
+
ShowModelFilter = true;
|
|
84
|
+
ShowAgentFilter = true;
|
|
85
|
+
ShowPromptFilter = true;
|
|
86
|
+
ShowStatusFilter = true;
|
|
87
|
+
ShowCompareToggle = true;
|
|
88
|
+
ShowExportButton = false;
|
|
89
|
+
Filters = { Models: [], Agents: [], Prompts: [], Statuses: [] };
|
|
90
|
+
TimeRangeChange = new EventEmitter();
|
|
91
|
+
FiltersChange = new EventEmitter();
|
|
92
|
+
CompareToggled = new EventEmitter();
|
|
93
|
+
ExportClicked = new EventEmitter();
|
|
94
|
+
ModelOptions = [];
|
|
95
|
+
AgentOptions = [];
|
|
96
|
+
PromptOptions = [];
|
|
97
|
+
StatusOptions = [
|
|
98
|
+
{ text: 'Success', value: 'Success' },
|
|
99
|
+
{ text: 'Error', value: 'Error' },
|
|
100
|
+
{ text: 'Running', value: 'Running' },
|
|
101
|
+
{ text: 'Pending', value: 'Pending' },
|
|
102
|
+
{ text: 'Canceled', value: 'Canceled' }
|
|
103
|
+
];
|
|
104
|
+
/** Default items shown when nothing is selected (the "All X" option) */
|
|
105
|
+
modelDefaultItem = { text: 'All Models', value: '' };
|
|
106
|
+
agentDefaultItem = { text: 'All Agents', value: '' };
|
|
107
|
+
promptDefaultItem = { text: 'All Prompts', value: '' };
|
|
108
|
+
statusDefaultItem = { text: 'All Statuses', value: '' };
|
|
109
|
+
compareActive = false;
|
|
110
|
+
ngOnInit() {
|
|
111
|
+
this.BuildOptions();
|
|
112
|
+
}
|
|
113
|
+
OnTimeRangeSelect(range) {
|
|
114
|
+
this.TimeRange = range;
|
|
115
|
+
this.TimeRangeChange.emit(range);
|
|
116
|
+
}
|
|
117
|
+
OnModelChange(event) {
|
|
118
|
+
const id = event ?? '';
|
|
119
|
+
this.Filters = { ...this.Filters, Models: id ? [id] : [] };
|
|
120
|
+
this.FiltersChange.emit(this.Filters);
|
|
121
|
+
}
|
|
122
|
+
OnAgentChange(event) {
|
|
123
|
+
const id = event ?? '';
|
|
124
|
+
this.Filters = { ...this.Filters, Agents: id ? [id] : [] };
|
|
125
|
+
this.FiltersChange.emit(this.Filters);
|
|
126
|
+
}
|
|
127
|
+
OnPromptChange(event) {
|
|
128
|
+
const id = event ?? '';
|
|
129
|
+
this.Filters = { ...this.Filters, Prompts: id ? [id] : [] };
|
|
130
|
+
this.FiltersChange.emit(this.Filters);
|
|
131
|
+
}
|
|
132
|
+
OnStatusChange(event) {
|
|
133
|
+
const status = event ?? '';
|
|
134
|
+
this.Filters = { ...this.Filters, Statuses: status ? [status] : [] };
|
|
135
|
+
this.FiltersChange.emit(this.Filters);
|
|
136
|
+
}
|
|
137
|
+
ToggleCompare() {
|
|
138
|
+
this.compareActive = !this.compareActive;
|
|
139
|
+
this.CompareToggled.emit(this.compareActive);
|
|
140
|
+
}
|
|
141
|
+
BuildOptions() {
|
|
142
|
+
const engine = AIEngineBase.Instance;
|
|
143
|
+
this.ModelOptions = engine.Models
|
|
144
|
+
.map(m => ({ text: m.Name ?? '', value: m.ID }))
|
|
145
|
+
.sort((a, b) => a.text.localeCompare(b.text));
|
|
146
|
+
this.AgentOptions = engine.Agents
|
|
147
|
+
.filter(a => a.Status === 'Active')
|
|
148
|
+
.map(a => ({ text: a.Name ?? '', value: a.ID }))
|
|
149
|
+
.sort((a, b) => a.text.localeCompare(b.text));
|
|
150
|
+
this.PromptOptions = engine.Prompts
|
|
151
|
+
.map(p => ({ text: p.Name ?? '', value: p.ID }))
|
|
152
|
+
.sort((a, b) => a.text.localeCompare(b.text));
|
|
153
|
+
}
|
|
154
|
+
static ɵfac = function AnalyticsFilterBarComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AnalyticsFilterBarComponent)(); };
|
|
155
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AnalyticsFilterBarComponent, selectors: [["app-analytics-filter-bar"]], inputs: { TimeRange: "TimeRange", TimeRangeOptions: "TimeRangeOptions", ShowModelFilter: "ShowModelFilter", ShowAgentFilter: "ShowAgentFilter", ShowPromptFilter: "ShowPromptFilter", ShowStatusFilter: "ShowStatusFilter", ShowCompareToggle: "ShowCompareToggle", ShowExportButton: "ShowExportButton", Filters: "Filters" }, outputs: { TimeRangeChange: "TimeRangeChange", FiltersChange: "FiltersChange", CompareToggled: "CompareToggled", ExportClicked: "ExportClicked" }, standalone: false, decls: 14, vars: 6, consts: [[1, "filter-bar"], [1, "filter-controls"], [1, "filter-label"], [1, "fa-solid", "fa-filter"], ["TextField", "text", "ValueField", "value", "Placeholder", "All Models", 3, "Data", "ValuePrimitive", "DefaultItem", "Filterable"], ["TextField", "text", "ValueField", "value", "Placeholder", "All Agents", 3, "Data", "ValuePrimitive", "DefaultItem", "Filterable"], ["TextField", "text", "ValueField", "value", "Placeholder", "All Prompts", 3, "Data", "ValuePrimitive", "DefaultItem", "Filterable"], ["TextField", "text", "ValueField", "value", "Placeholder", "All Statuses", 3, "Data", "ValuePrimitive", "DefaultItem"], [1, "compare-btn", 3, "active"], [1, "export-btn"], [1, "time-chips"], [1, "time-chip", 3, "active"], ["TextField", "text", "ValueField", "value", "Placeholder", "All Models", 3, "ValueChange", "Data", "ValuePrimitive", "DefaultItem", "Filterable"], ["TextField", "text", "ValueField", "value", "Placeholder", "All Agents", 3, "ValueChange", "Data", "ValuePrimitive", "DefaultItem", "Filterable"], ["TextField", "text", "ValueField", "value", "Placeholder", "All Prompts", 3, "ValueChange", "Data", "ValuePrimitive", "DefaultItem", "Filterable"], ["TextField", "text", "ValueField", "value", "Placeholder", "All Statuses", 3, "ValueChange", "Data", "ValuePrimitive", "DefaultItem"], [1, "compare-btn", 3, "click"], [1, "fa-solid", "fa-code-compare"], [1, "export-btn", 3, "click"], [1, "fa-solid", "fa-download"], [1, "time-chip", 3, "click"]], template: function AnalyticsFilterBarComponent_Template(rf, ctx) { if (rf & 1) {
|
|
156
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "span", 2);
|
|
157
|
+
i0.ɵɵelement(3, "i", 3);
|
|
158
|
+
i0.ɵɵtext(4, " Filters: ");
|
|
159
|
+
i0.ɵɵelementEnd();
|
|
160
|
+
i0.ɵɵconditionalCreate(5, AnalyticsFilterBarComponent_Conditional_5_Template, 1, 4, "mj-dropdown", 4);
|
|
161
|
+
i0.ɵɵconditionalCreate(6, AnalyticsFilterBarComponent_Conditional_6_Template, 1, 4, "mj-dropdown", 5);
|
|
162
|
+
i0.ɵɵconditionalCreate(7, AnalyticsFilterBarComponent_Conditional_7_Template, 1, 4, "mj-dropdown", 6);
|
|
163
|
+
i0.ɵɵconditionalCreate(8, AnalyticsFilterBarComponent_Conditional_8_Template, 1, 3, "mj-dropdown", 7);
|
|
164
|
+
i0.ɵɵconditionalCreate(9, AnalyticsFilterBarComponent_Conditional_9_Template, 3, 2, "button", 8);
|
|
165
|
+
i0.ɵɵconditionalCreate(10, AnalyticsFilterBarComponent_Conditional_10_Template, 3, 0, "button", 9);
|
|
166
|
+
i0.ɵɵelementEnd();
|
|
167
|
+
i0.ɵɵelementStart(11, "div", 10);
|
|
168
|
+
i0.ɵɵrepeaterCreate(12, AnalyticsFilterBarComponent_For_13_Template, 2, 3, "button", 11, i0.ɵɵrepeaterTrackByIdentity);
|
|
169
|
+
i0.ɵɵelementEnd()();
|
|
170
|
+
} if (rf & 2) {
|
|
171
|
+
i0.ɵɵadvance(5);
|
|
172
|
+
i0.ɵɵconditional(ctx.ShowModelFilter ? 5 : -1);
|
|
173
|
+
i0.ɵɵadvance();
|
|
174
|
+
i0.ɵɵconditional(ctx.ShowAgentFilter ? 6 : -1);
|
|
175
|
+
i0.ɵɵadvance();
|
|
176
|
+
i0.ɵɵconditional(ctx.ShowPromptFilter ? 7 : -1);
|
|
177
|
+
i0.ɵɵadvance();
|
|
178
|
+
i0.ɵɵconditional(ctx.ShowStatusFilter ? 8 : -1);
|
|
179
|
+
i0.ɵɵadvance();
|
|
180
|
+
i0.ɵɵconditional(ctx.ShowCompareToggle ? 9 : -1);
|
|
181
|
+
i0.ɵɵadvance();
|
|
182
|
+
i0.ɵɵconditional(ctx.ShowExportButton ? 10 : -1);
|
|
183
|
+
i0.ɵɵadvance(2);
|
|
184
|
+
i0.ɵɵrepeater(ctx.TimeRangeOptions);
|
|
185
|
+
} }, dependencies: [i1.MJDropdownComponent], styles: [".filter-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 12px 16px;\n flex-wrap: wrap;\n }\n\n .filter-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .filter-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .filter-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n\n [_nghost-%COMP%] mj-dropdown {\n min-width: 160px;\n max-width: 220px;\n }\n\n [_nghost-%COMP%] mj-dropdown .mj-dropdown {\n font-size: 13px;\n border-radius: 6px;\n }\n\n .compare-btn[_ngcontent-%COMP%], \n .export-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n }\n\n .compare-btn[_ngcontent-%COMP%]:hover, \n .export-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .compare-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n\n .time-chips[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n }\n\n .time-chip[_ngcontent-%COMP%] {\n padding: 5px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n white-space: nowrap;\n }\n\n .time-chip[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .time-chip.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n font-weight: 600;\n }\n\n @media (max-width: 768px) {\n .filter-bar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n\n .time-chips[_ngcontent-%COMP%] {\n margin-left: 0;\n justify-content: flex-start;\n flex-wrap: wrap;\n }\n }"] });
|
|
186
|
+
}
|
|
187
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AnalyticsFilterBarComponent, [{
|
|
188
|
+
type: Component,
|
|
189
|
+
args: [{ standalone: false, selector: 'app-analytics-filter-bar', template: `
|
|
190
|
+
<div class="filter-bar">
|
|
191
|
+
<div class="filter-controls">
|
|
192
|
+
<span class="filter-label">
|
|
193
|
+
<i class="fa-solid fa-filter"></i>
|
|
194
|
+
Filters:
|
|
195
|
+
</span>
|
|
196
|
+
|
|
197
|
+
@if (ShowModelFilter) {
|
|
198
|
+
<mj-dropdown
|
|
199
|
+
[Data]="ModelOptions"
|
|
200
|
+
TextField="text"
|
|
201
|
+
ValueField="value"
|
|
202
|
+
[ValuePrimitive]="true"
|
|
203
|
+
[DefaultItem]="modelDefaultItem"
|
|
204
|
+
[Filterable]="ModelOptions.length > 10"
|
|
205
|
+
Placeholder="All Models"
|
|
206
|
+
(ValueChange)="OnModelChange($event)">
|
|
207
|
+
</mj-dropdown>
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@if (ShowAgentFilter) {
|
|
211
|
+
<mj-dropdown
|
|
212
|
+
[Data]="AgentOptions"
|
|
213
|
+
TextField="text"
|
|
214
|
+
ValueField="value"
|
|
215
|
+
[ValuePrimitive]="true"
|
|
216
|
+
[DefaultItem]="agentDefaultItem"
|
|
217
|
+
[Filterable]="AgentOptions.length > 10"
|
|
218
|
+
Placeholder="All Agents"
|
|
219
|
+
(ValueChange)="OnAgentChange($event)">
|
|
220
|
+
</mj-dropdown>
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@if (ShowPromptFilter) {
|
|
224
|
+
<mj-dropdown
|
|
225
|
+
[Data]="PromptOptions"
|
|
226
|
+
TextField="text"
|
|
227
|
+
ValueField="value"
|
|
228
|
+
[ValuePrimitive]="true"
|
|
229
|
+
[DefaultItem]="promptDefaultItem"
|
|
230
|
+
[Filterable]="PromptOptions.length > 10"
|
|
231
|
+
Placeholder="All Prompts"
|
|
232
|
+
(ValueChange)="OnPromptChange($event)">
|
|
233
|
+
</mj-dropdown>
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
@if (ShowStatusFilter) {
|
|
237
|
+
<mj-dropdown
|
|
238
|
+
[Data]="StatusOptions"
|
|
239
|
+
TextField="text"
|
|
240
|
+
ValueField="value"
|
|
241
|
+
[ValuePrimitive]="true"
|
|
242
|
+
[DefaultItem]="statusDefaultItem"
|
|
243
|
+
Placeholder="All Statuses"
|
|
244
|
+
(ValueChange)="OnStatusChange($event)">
|
|
245
|
+
</mj-dropdown>
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@if (ShowCompareToggle) {
|
|
249
|
+
<button
|
|
250
|
+
class="compare-btn"
|
|
251
|
+
[class.active]="compareActive"
|
|
252
|
+
(click)="ToggleCompare()">
|
|
253
|
+
<i class="fa-solid fa-code-compare"></i>
|
|
254
|
+
Compare
|
|
255
|
+
</button>
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
@if (ShowExportButton) {
|
|
259
|
+
<button class="export-btn" (click)="ExportClicked.emit()">
|
|
260
|
+
<i class="fa-solid fa-download"></i>
|
|
261
|
+
Export
|
|
262
|
+
</button>
|
|
263
|
+
}
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
<div class="time-chips">
|
|
267
|
+
@for (option of TimeRangeOptions; track option) {
|
|
268
|
+
<button
|
|
269
|
+
class="time-chip"
|
|
270
|
+
[class.active]="TimeRange === option"
|
|
271
|
+
(click)="OnTimeRangeSelect(option)">
|
|
272
|
+
{{ option }}
|
|
273
|
+
</button>
|
|
274
|
+
}
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
`, styles: ["\n .filter-bar {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 12px 16px;\n flex-wrap: wrap;\n }\n\n .filter-controls {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .filter-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .filter-label i {\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n\n :host ::ng-deep mj-dropdown {\n min-width: 160px;\n max-width: 220px;\n }\n\n :host ::ng-deep mj-dropdown .mj-dropdown {\n font-size: 13px;\n border-radius: 6px;\n }\n\n .compare-btn,\n .export-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n }\n\n .compare-btn:hover,\n .export-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .compare-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n\n .time-chips {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n }\n\n .time-chip {\n padding: 5px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n white-space: nowrap;\n }\n\n .time-chip:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .time-chip.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n font-weight: 600;\n }\n\n @media (max-width: 768px) {\n .filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .time-chips {\n margin-left: 0;\n justify-content: flex-start;\n flex-wrap: wrap;\n }\n }\n "] }]
|
|
278
|
+
}], null, { TimeRange: [{
|
|
279
|
+
type: Input
|
|
280
|
+
}], TimeRangeOptions: [{
|
|
281
|
+
type: Input
|
|
282
|
+
}], ShowModelFilter: [{
|
|
283
|
+
type: Input
|
|
284
|
+
}], ShowAgentFilter: [{
|
|
285
|
+
type: Input
|
|
286
|
+
}], ShowPromptFilter: [{
|
|
287
|
+
type: Input
|
|
288
|
+
}], ShowStatusFilter: [{
|
|
289
|
+
type: Input
|
|
290
|
+
}], ShowCompareToggle: [{
|
|
291
|
+
type: Input
|
|
292
|
+
}], ShowExportButton: [{
|
|
293
|
+
type: Input
|
|
294
|
+
}], Filters: [{
|
|
295
|
+
type: Input
|
|
296
|
+
}], TimeRangeChange: [{
|
|
297
|
+
type: Output
|
|
298
|
+
}], FiltersChange: [{
|
|
299
|
+
type: Output
|
|
300
|
+
}], CompareToggled: [{
|
|
301
|
+
type: Output
|
|
302
|
+
}], ExportClicked: [{
|
|
303
|
+
type: Output
|
|
304
|
+
}] }); })();
|
|
305
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AnalyticsFilterBarComponent, { className: "AnalyticsFilterBarComponent", filePath: "src/AI/components/analytics/analytics-filter-bar.component.ts", lineNumber: 229 }); })();
|
|
306
|
+
//# sourceMappingURL=analytics-filter-bar.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-filter-bar.component.js","sourceRoot":"","sources":["../../../../src/AI/components/analytics/analytics-filter-bar.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Reusable filter bar for AI Analytics dashboard sections.\n *\n * Provides time-range chips, model/agent/prompt/status dropdowns\n * (using mj-dropdown), a compare toggle, and an optional export button.\n * Each section shows/hides filters via boolean inputs.\n */\n\nimport { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { GlobalFilterState } from '../../interfaces/analytics-preferences.interface';\n\ninterface FilterOption {\n text: string;\n value: string;\n [key: string]: unknown;\n}\n\n@Component({\n standalone: false,\n selector: 'app-analytics-filter-bar',\n template: `\n <div class=\"filter-bar\">\n <div class=\"filter-controls\">\n <span class=\"filter-label\">\n <i class=\"fa-solid fa-filter\"></i>\n Filters:\n </span>\n\n @if (ShowModelFilter) {\n <mj-dropdown\n [Data]=\"ModelOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [DefaultItem]=\"modelDefaultItem\"\n [Filterable]=\"ModelOptions.length > 10\"\n Placeholder=\"All Models\"\n (ValueChange)=\"OnModelChange($event)\">\n </mj-dropdown>\n }\n\n @if (ShowAgentFilter) {\n <mj-dropdown\n [Data]=\"AgentOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [DefaultItem]=\"agentDefaultItem\"\n [Filterable]=\"AgentOptions.length > 10\"\n Placeholder=\"All Agents\"\n (ValueChange)=\"OnAgentChange($event)\">\n </mj-dropdown>\n }\n\n @if (ShowPromptFilter) {\n <mj-dropdown\n [Data]=\"PromptOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [DefaultItem]=\"promptDefaultItem\"\n [Filterable]=\"PromptOptions.length > 10\"\n Placeholder=\"All Prompts\"\n (ValueChange)=\"OnPromptChange($event)\">\n </mj-dropdown>\n }\n\n @if (ShowStatusFilter) {\n <mj-dropdown\n [Data]=\"StatusOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [DefaultItem]=\"statusDefaultItem\"\n Placeholder=\"All Statuses\"\n (ValueChange)=\"OnStatusChange($event)\">\n </mj-dropdown>\n }\n\n @if (ShowCompareToggle) {\n <button\n class=\"compare-btn\"\n [class.active]=\"compareActive\"\n (click)=\"ToggleCompare()\">\n <i class=\"fa-solid fa-code-compare\"></i>\n Compare\n </button>\n }\n\n @if (ShowExportButton) {\n <button class=\"export-btn\" (click)=\"ExportClicked.emit()\">\n <i class=\"fa-solid fa-download\"></i>\n Export\n </button>\n }\n </div>\n\n <div class=\"time-chips\">\n @for (option of TimeRangeOptions; track option) {\n <button\n class=\"time-chip\"\n [class.active]=\"TimeRange === option\"\n (click)=\"OnTimeRangeSelect(option)\">\n {{ option }}\n </button>\n }\n </div>\n </div>\n `,\n styles: [`\n .filter-bar {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 12px 16px;\n flex-wrap: wrap;\n }\n\n .filter-controls {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .filter-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .filter-label i {\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n\n :host ::ng-deep mj-dropdown {\n min-width: 160px;\n max-width: 220px;\n }\n\n :host ::ng-deep mj-dropdown .mj-dropdown {\n font-size: 13px;\n border-radius: 6px;\n }\n\n .compare-btn,\n .export-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n }\n\n .compare-btn:hover,\n .export-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .compare-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n\n .time-chips {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n }\n\n .time-chip {\n padding: 5px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n white-space: nowrap;\n }\n\n .time-chip:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .time-chip.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n font-weight: 600;\n }\n\n @media (max-width: 768px) {\n .filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .time-chips {\n margin-left: 0;\n justify-content: flex-start;\n flex-wrap: wrap;\n }\n }\n `]\n})\nexport class AnalyticsFilterBarComponent implements OnInit {\n @Input() TimeRange = '24h';\n @Input() TimeRangeOptions: string[] = ['1h', '6h', '24h', '7d', '30d'];\n @Input() ShowModelFilter = true;\n @Input() ShowAgentFilter = true;\n @Input() ShowPromptFilter = true;\n @Input() ShowStatusFilter = true;\n @Input() ShowCompareToggle = true;\n @Input() ShowExportButton = false;\n @Input() Filters: GlobalFilterState = { Models: [], Agents: [], Prompts: [], Statuses: [] };\n\n @Output() TimeRangeChange = new EventEmitter<string>();\n @Output() FiltersChange = new EventEmitter<GlobalFilterState>();\n @Output() CompareToggled = new EventEmitter<boolean>();\n @Output() ExportClicked = new EventEmitter<void>();\n\n public ModelOptions: FilterOption[] = [];\n public AgentOptions: FilterOption[] = [];\n public PromptOptions: FilterOption[] = [];\n public StatusOptions: FilterOption[] = [\n { text: 'Success', value: 'Success' },\n { text: 'Error', value: 'Error' },\n { text: 'Running', value: 'Running' },\n { text: 'Pending', value: 'Pending' },\n { text: 'Canceled', value: 'Canceled' }\n ];\n\n /** Default items shown when nothing is selected (the \"All X\" option) */\n public modelDefaultItem: FilterOption = { text: 'All Models', value: '' };\n public agentDefaultItem: FilterOption = { text: 'All Agents', value: '' };\n public promptDefaultItem: FilterOption = { text: 'All Prompts', value: '' };\n public statusDefaultItem: FilterOption = { text: 'All Statuses', value: '' };\n\n public compareActive = false;\n\n ngOnInit(): void {\n this.BuildOptions();\n }\n\n public OnTimeRangeSelect(range: string): void {\n this.TimeRange = range;\n this.TimeRangeChange.emit(range);\n }\n\n public OnModelChange(event: unknown): void {\n const id = (event as string) ?? '';\n this.Filters = { ...this.Filters, Models: id ? [id] : [] };\n this.FiltersChange.emit(this.Filters);\n }\n\n public OnAgentChange(event: unknown): void {\n const id = (event as string) ?? '';\n this.Filters = { ...this.Filters, Agents: id ? [id] : [] };\n this.FiltersChange.emit(this.Filters);\n }\n\n public OnPromptChange(event: unknown): void {\n const id = (event as string) ?? '';\n this.Filters = { ...this.Filters, Prompts: id ? [id] : [] };\n this.FiltersChange.emit(this.Filters);\n }\n\n public OnStatusChange(event: unknown): void {\n const status = (event as string) ?? '';\n this.Filters = { ...this.Filters, Statuses: status ? [status] : [] };\n this.FiltersChange.emit(this.Filters);\n }\n\n public ToggleCompare(): void {\n this.compareActive = !this.compareActive;\n this.CompareToggled.emit(this.compareActive);\n }\n\n private BuildOptions(): void {\n const engine = AIEngineBase.Instance;\n\n this.ModelOptions = engine.Models\n .map(m => ({ text: m.Name ?? '', value: m.ID }))\n .sort((a, b) => a.text.localeCompare(b.text));\n\n this.AgentOptions = engine.Agents\n .filter(a => a.Status === 'Active')\n .map(a => ({ text: a.Name ?? '', value: a.ID }))\n .sort((a, b) => a.text.localeCompare(b.text));\n\n this.PromptOptions = engine.Prompts\n .map(p => ({ text: p.Name ?? '', value: p.ID }))\n .sort((a, b) => a.text.localeCompare(b.text));\n }\n}\n"]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Cost & Budget Analytics -- Option B.
|
|
3
|
+
*
|
|
4
|
+
* Displays cost KPIs with period deltas, a daily cost bar chart with anomaly detection,
|
|
5
|
+
* a cost breakdown treemap, and a detailed cost-by-model table with CSV export.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter, OnInit, OnDestroy } from '@angular/core';
|
|
8
|
+
import { GlobalFilterState } from '../../../interfaces/analytics-preferences.interface';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
interface CostKpi {
|
|
11
|
+
Label: string;
|
|
12
|
+
Value: string;
|
|
13
|
+
Delta: number | null;
|
|
14
|
+
DeltaDirection: 'up' | 'down' | 'stable';
|
|
15
|
+
Highlighted: boolean;
|
|
16
|
+
Icon: string;
|
|
17
|
+
}
|
|
18
|
+
interface DailyBar {
|
|
19
|
+
Date: string;
|
|
20
|
+
Label: string;
|
|
21
|
+
Cost: number;
|
|
22
|
+
HeightPercent: number;
|
|
23
|
+
IsAnomaly: boolean;
|
|
24
|
+
}
|
|
25
|
+
interface TreemapCell {
|
|
26
|
+
Label: string;
|
|
27
|
+
Cost: number;
|
|
28
|
+
Percent: number;
|
|
29
|
+
Color: string;
|
|
30
|
+
GridArea: string;
|
|
31
|
+
}
|
|
32
|
+
interface CostByModelRow {
|
|
33
|
+
Model: string;
|
|
34
|
+
Vendor: string;
|
|
35
|
+
Runs: number;
|
|
36
|
+
InputTokens: number;
|
|
37
|
+
OutputTokens: number;
|
|
38
|
+
InputCost: number;
|
|
39
|
+
OutputCost: number;
|
|
40
|
+
TotalCost: number;
|
|
41
|
+
PercentOfTotal: number;
|
|
42
|
+
}
|
|
43
|
+
export declare class AnalyticsCostBudgetComponent implements OnInit, OnDestroy {
|
|
44
|
+
TimeRange: string;
|
|
45
|
+
Filters: GlobalFilterState;
|
|
46
|
+
TimeRangeChange: EventEmitter<string>;
|
|
47
|
+
FiltersChange: EventEmitter<GlobalFilterState>;
|
|
48
|
+
private cdr;
|
|
49
|
+
private destroy$;
|
|
50
|
+
IsLoading: boolean;
|
|
51
|
+
TimeRangeOptionsList: string[];
|
|
52
|
+
CostKpis: CostKpi[];
|
|
53
|
+
DailyBars: DailyBar[];
|
|
54
|
+
AvgLinePercent: number;
|
|
55
|
+
TreemapCells: TreemapCell[];
|
|
56
|
+
CostByModelRows: CostByModelRow[];
|
|
57
|
+
private allRuns;
|
|
58
|
+
private previousPeriodRuns;
|
|
59
|
+
ngOnInit(): void;
|
|
60
|
+
ngOnDestroy(): void;
|
|
61
|
+
OnTimeRangeChange(range: string): void;
|
|
62
|
+
OnFiltersChange(filters: GlobalFilterState): void;
|
|
63
|
+
FormatCurrency(value: number, decimals?: number): string;
|
|
64
|
+
ExportCSV(): void;
|
|
65
|
+
private LoadData;
|
|
66
|
+
private computeKpis;
|
|
67
|
+
private computeDailyBars;
|
|
68
|
+
private computeTreemap;
|
|
69
|
+
private computeCostByModel;
|
|
70
|
+
private sumCostInRange;
|
|
71
|
+
private getDateBounds;
|
|
72
|
+
private buildModelFilter;
|
|
73
|
+
private combineDateAndModelFilter;
|
|
74
|
+
private formatBarLabel;
|
|
75
|
+
private downloadCSV;
|
|
76
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AnalyticsCostBudgetComponent, never>;
|
|
77
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AnalyticsCostBudgetComponent, "app-analytics-cost-budget", never, { "TimeRange": { "alias": "TimeRange"; "required": false; }; "Filters": { "alias": "Filters"; "required": false; }; }, { "TimeRangeChange": "TimeRangeChange"; "FiltersChange": "FiltersChange"; }, never, never, false, never>;
|
|
78
|
+
}
|
|
79
|
+
export declare function LoadAnalyticsCostBudget(): void;
|
|
80
|
+
export {};
|
|
81
|
+
//# sourceMappingURL=cost-budget.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-budget.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/analytics/cost-budget/cost-budget.component.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACuB,YAAY,EACtC,MAAM,EAAE,SAAS,EACpB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qDAAqD,CAAC;;AAmBxF,UAAU,OAAO;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,cAAc,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC;IACzC,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,QAAQ;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,WAAW;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,cAAc;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAkBD,qBAogBa,4BAA6B,YAAW,MAAM,EAAE,SAAS;IACzD,SAAS,SAAQ;IACjB,OAAO,EAAE,iBAAiB,CAAyD;IAElF,eAAe,uBAA8B;IAC7C,aAAa,kCAAyC;IAEhE,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,QAAQ,CAAuB;IAEhC,SAAS,UAAS;IAClB,oBAAoB,WAAsB;IAE1C,QAAQ,EAAE,OAAO,EAAE,CAAM;IACzB,SAAS,EAAE,QAAQ,EAAE,CAAM;IAC3B,cAAc,SAAK;IACnB,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,eAAe,EAAE,cAAc,EAAE,CAAM;IAE9C,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,kBAAkB,CAAyB;IAEnD,QAAQ,IAAI,IAAI;IAIhB,WAAW,IAAI,IAAI;IAOZ,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMtC,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAMjD,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM;IAMnD,SAAS,IAAI,IAAI;YAWV,QAAQ;IA8CtB,OAAO,CAAC,WAAW;IAuDnB,OAAO,CAAC,gBAAgB;IA+BxB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,yBAAyB;IASjC,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,WAAW;yCAxSV,4BAA4B;2CAA5B,4BAA4B;CAiTxC;AAED,wBAAgB,uBAAuB,SAAoC"}
|