@memberjunction/ng-dashboards 6.2.0-edge.5 → 6.2.0-edge.6
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/README.md +28 -0
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +15 -7
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +7 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +209 -57
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts +12 -11
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js +15 -15
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +28 -16
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +1 -0
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +30 -6
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +15 -7
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- package/dist/AI/components/vectors/sensitive-fields.d.ts +9 -4
- package/dist/AI/components/vectors/sensitive-fields.d.ts.map +1 -1
- package/dist/AI/components/vectors/sensitive-fields.js +39 -14
- package/dist/AI/components/vectors/sensitive-fields.js.map +1 -1
- package/dist/AI/components/vectors/vector-document-rules.d.ts +13 -0
- package/dist/AI/components/vectors/vector-document-rules.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-document-rules.js +14 -0
- package/dist/AI/components/vectors/vector-document-rules.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +34 -14
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +127 -50
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-store-selection.d.ts +32 -0
- package/dist/AI/components/vectors/vector-store-selection.d.ts.map +1 -0
- package/dist/AI/components/vectors/vector-store-selection.js +57 -0
- package/dist/AI/components/vectors/vector-store-selection.js.map +1 -0
- package/dist/ChiefOfStaff/chief-of-staff-agent-context.d.ts +236 -0
- package/dist/ChiefOfStaff/chief-of-staff-agent-context.d.ts.map +1 -0
- package/dist/ChiefOfStaff/chief-of-staff-agent-context.js +374 -0
- package/dist/ChiefOfStaff/chief-of-staff-agent-context.js.map +1 -0
- package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.d.ts +195 -0
- package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.d.ts.map +1 -0
- package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.js +2910 -0
- package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.js.map +1 -0
- package/dist/ChiefOfStaff/index.d.ts +3 -0
- package/dist/ChiefOfStaff/index.d.ts.map +1 -0
- package/dist/ChiefOfStaff/index.js +3 -0
- package/dist/ChiefOfStaff/index.js.map +1 -0
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +2 -1
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +23 -18
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +11 -10
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/DashboardEditor/dashboard-editor.component.d.ts +17 -2
- package/dist/DashboardEditor/dashboard-editor.component.d.ts.map +1 -1
- package/dist/DashboardEditor/dashboard-editor.component.js +94 -43
- package/dist/DashboardEditor/dashboard-editor.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +24 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +146 -50
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/models/explorer-state.interface.d.ts +2 -0
- package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
- package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
- package/dist/LoginStudio/login-studio-resource.component.d.ts +10 -2
- package/dist/LoginStudio/login-studio-resource.component.d.ts.map +1 -1
- package/dist/LoginStudio/login-studio-resource.component.js +110 -77
- package/dist/LoginStudio/login-studio-resource.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.d.ts +24 -4
- package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +118 -65
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/PredictiveStudio/business-predictions.view-models.d.ts +1 -1
- package/dist/PredictiveStudio/business-predictions.view-models.d.ts.map +1 -1
- package/dist/PredictiveStudio/business-predictions.view-models.js +3 -3
- package/dist/PredictiveStudio/business-predictions.view-models.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts +6 -63
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.js +256 -521
- package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts +0 -18
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js +122 -249
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts +5 -9
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipelines.component.js +98 -130
- package/dist/PredictiveStudio/components/ps-pipelines.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts +53 -4
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js +335 -326
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-row-drivers.component.d.ts +19 -0
- package/dist/PredictiveStudio/components/ps-row-drivers.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-row-drivers.component.js +85 -0
- package/dist/PredictiveStudio/components/ps-row-drivers.component.js.map +1 -0
- package/dist/PredictiveStudio/engine/predictive-studio.engine.d.ts +19 -1
- package/dist/PredictiveStudio/engine/predictive-studio.engine.d.ts.map +1 -1
- package/dist/PredictiveStudio/engine/predictive-studio.engine.js +51 -2
- package/dist/PredictiveStudio/engine/predictive-studio.engine.js.map +1 -1
- package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts +3 -1
- package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts.map +1 -1
- package/dist/PredictiveStudio/predictive-studio-agent-context.js +3 -0
- package/dist/PredictiveStudio/predictive-studio-agent-context.js.map +1 -1
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts +27 -4
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts.map +1 -1
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js +94 -61
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts +29 -5
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +185 -103
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +22 -21
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +8 -2
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +71 -71
- package/dist/PredictiveStudio/at-risk.view-models.d.ts +0 -120
- package/dist/PredictiveStudio/at-risk.view-models.d.ts.map +0 -1
- package/dist/PredictiveStudio/at-risk.view-models.js +0 -261
- package/dist/PredictiveStudio/at-risk.view-models.js.map +0 -1
- package/dist/PredictiveStudio/components/ps-confirm-modal.component.d.ts +0 -109
- package/dist/PredictiveStudio/components/ps-confirm-modal.component.d.ts.map +0 -1
- package/dist/PredictiveStudio/components/ps-confirm-modal.component.js +0 -323
- package/dist/PredictiveStudio/components/ps-confirm-modal.component.js.map +0 -1
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts +0 -137
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts.map +0 -1
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js +0 -826
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js.map +0 -1
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, unit-testable helpers for the "My Chief of Staff" Executive Cockpit's
|
|
3
|
+
* agent context + client tools.
|
|
4
|
+
*
|
|
5
|
+
* 🚨 SAFETY BOUNDARY 🚨
|
|
6
|
+
* The Chief of Staff Cockpit exposes ONLY navigation / tab-switch / filter / search /
|
|
7
|
+
* refresh / detail-view tools to the co-agent. DELIBERATELY NOT exposed as client tools
|
|
8
|
+
* (mutations stay human-driven in the UI):
|
|
9
|
+
* - Approving or rejecting `MJ: AI Agent Requests`
|
|
10
|
+
* - Modifying or saving `MJ: AI Agent User Policies` governance toggles / thresholds
|
|
11
|
+
* - Triggering "Wake Now" or pausing/resuming `MJ: User Routines`
|
|
12
|
+
*
|
|
13
|
+
* Published context exposes only aggregate counts, active tab/filter state, governance
|
|
14
|
+
* mode summaries, and bounded display names (capped at 25) — never raw request payloads,
|
|
15
|
+
* custom instructions overrides, or private message content.
|
|
16
|
+
*/
|
|
17
|
+
import { CompositeKey } from '@memberjunction/core';
|
|
18
|
+
import { EscapeSQLString, GroupByUUID, UUIDsEqual } from '@memberjunction/global';
|
|
19
|
+
import { AGENT_CONTEXT_NAME_LIST_CAP, BoundNameList, ValidateEnumParam, ValidateStringParam, } from '../shared/agent-tool-validation';
|
|
20
|
+
/**
|
|
21
|
+
* The cockpit serves one agent, identified by its metadata name. The id is resolved at runtime
|
|
22
|
+
* through `AIEngineBase.GetAgentByName`, never hardcoded.
|
|
23
|
+
*/
|
|
24
|
+
export const CHIEF_OF_STAFF_AGENT_NAME = 'Chief of Staff';
|
|
25
|
+
export const VALID_CHIEF_OF_STAFF_TABS = [
|
|
26
|
+
'overview',
|
|
27
|
+
'priorities',
|
|
28
|
+
'approvals-wakes',
|
|
29
|
+
'governance',
|
|
30
|
+
];
|
|
31
|
+
export const VALID_HEALTH_FILTERS = [
|
|
32
|
+
'all',
|
|
33
|
+
'OnTrack',
|
|
34
|
+
'AtRisk',
|
|
35
|
+
'OffTrack',
|
|
36
|
+
'Completed',
|
|
37
|
+
'Paused',
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Returns `true` when an `MJ: AI Agent Requests` row represents an actionable approval or
|
|
41
|
+
* review request for the Executive Cockpit's Pending Approvals queue, and `false` when it
|
|
42
|
+
* is a conversational `Information` turn created by `BaseAgent` when ending a chat turn.
|
|
43
|
+
*/
|
|
44
|
+
export function IsApprovalRequest(req) {
|
|
45
|
+
// The RequestType virtual field carries the type name; classify on it alone.
|
|
46
|
+
const typeName = req.RequestType?.trim().toLowerCase() ?? '';
|
|
47
|
+
return typeName !== 'information';
|
|
48
|
+
}
|
|
49
|
+
export function ParseOptionalDate(val) {
|
|
50
|
+
if (!val) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
if (val instanceof Date) {
|
|
54
|
+
return isNaN(val.getTime()) ? null : val;
|
|
55
|
+
}
|
|
56
|
+
const parsed = new Date(val);
|
|
57
|
+
return isNaN(parsed.getTime()) ? null : parsed;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Builds the primary key of a BizApps task from the entity's own primary key column(s) and the
|
|
61
|
+
* in-memory row. Tasks is an OpenApp entity, so neither the column name nor the column count is
|
|
62
|
+
* assumed; the same key feeds `OpenEntityRecord` and the `PrimaryKey` parameter of `Update Record`.
|
|
63
|
+
*/
|
|
64
|
+
export function BuildTaskRecordKey(entityInfo, task) {
|
|
65
|
+
return CompositeKey.FromEntityRecord(entityInfo, { ...task });
|
|
66
|
+
}
|
|
67
|
+
export function IsTaskPriorityObjective(task) {
|
|
68
|
+
if (task.IsPriority === true || task.IsPriority === 1) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
const typeLabel = (task.Type ?? task.TaskType ?? '').toLowerCase();
|
|
72
|
+
if (typeLabel.includes('priority') ||
|
|
73
|
+
typeLabel.includes('objective') ||
|
|
74
|
+
typeLabel.includes('okr')) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return task.ParentID == null && (task.HealthStatus != null || task.PlanningPeriod != null);
|
|
78
|
+
}
|
|
79
|
+
export function NormalizeTaskHealth(task) {
|
|
80
|
+
if (task.Status === 'Completed' || task.Status === 'Done' || task.HealthStatus === 'Completed') {
|
|
81
|
+
return 'Completed';
|
|
82
|
+
}
|
|
83
|
+
if (task.HealthStatus === 'AtRisk' || task.HealthStatus === 'OffTrack' || task.HealthStatus === 'Paused') {
|
|
84
|
+
return task.HealthStatus;
|
|
85
|
+
}
|
|
86
|
+
return 'OnTrack';
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Percent progress from `BaselineValue` toward `TargetValue`, clamped to 0-100.
|
|
90
|
+
* Honors `MetricDirection` implicitly: a Down target (target < baseline) measures reduction.
|
|
91
|
+
* Returns null when there is no target or the target equals the baseline (no measurable span).
|
|
92
|
+
*/
|
|
93
|
+
export function ComputeTaskMetricPercent(task) {
|
|
94
|
+
if (task.TargetValue == null) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const baseline = task.BaselineValue ?? 0;
|
|
98
|
+
const span = task.TargetValue - baseline;
|
|
99
|
+
if (span === 0) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const current = task.CurrentValue ?? baseline;
|
|
103
|
+
const raw = ((current - baseline) / span) * 100;
|
|
104
|
+
return Math.max(0, Math.min(100, Math.round(raw)));
|
|
105
|
+
}
|
|
106
|
+
export function BuildCockpitScopeFilters(currentUserId, chiefOfStaffAgentId) {
|
|
107
|
+
const user = EscapeSQLString(currentUserId);
|
|
108
|
+
const agent = EscapeSQLString(chiefOfStaffAgentId);
|
|
109
|
+
return {
|
|
110
|
+
Policy: `AgentID = '${agent}' AND UserID = '${user}'`,
|
|
111
|
+
Routines: `UserID = '${user}' AND (RoutineType = 'AgentWake' OR TargetID = '${agent}')`,
|
|
112
|
+
Requests: `AgentID = '${agent}' AND RequestForUserID = '${user}' AND (RequestType IS NULL OR RequestType <> 'Information')`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** OpenApp entity holding the person linked to the signed-in MJ user (`LinkedUserID`). */
|
|
116
|
+
export const BIZAPPS_PEOPLE_ENTITY_NAME = 'MJ_BizApps_Common: People';
|
|
117
|
+
/** OpenApp entity linking tasks to the people assigned to them. */
|
|
118
|
+
export const BIZAPPS_TASK_ASSIGNMENTS_ENTITY_NAME = 'MJ_BizApps_Tasks: Task Assignments';
|
|
119
|
+
/** CSS modifier for a task priority badge, keyed by the Tasks `Priority` value list (Critical/High/Medium/Low). */
|
|
120
|
+
export function GetTaskPriorityClass(priority) {
|
|
121
|
+
switch ((priority ?? '').toLowerCase()) {
|
|
122
|
+
case 'critical':
|
|
123
|
+
return 'priority-critical';
|
|
124
|
+
case 'high':
|
|
125
|
+
return 'priority-high';
|
|
126
|
+
case 'low':
|
|
127
|
+
return 'priority-low';
|
|
128
|
+
default:
|
|
129
|
+
return 'priority-normal';
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Resolve the BizApps person linked to `currentUserId` and the filter that limits the Tasks query to work
|
|
134
|
+
* that person created or is assigned to. Throws when either lookup fails so the caller can show the error.
|
|
135
|
+
*/
|
|
136
|
+
export async function ResolvePersonTaskScope(runner, currentUserId) {
|
|
137
|
+
const people = await runner.RunView({
|
|
138
|
+
EntityName: BIZAPPS_PEOPLE_ENTITY_NAME,
|
|
139
|
+
ExtraFilter: `LinkedUserID = '${EscapeSQLString(currentUserId)}'`,
|
|
140
|
+
Fields: ['ID'],
|
|
141
|
+
MaxRows: 1,
|
|
142
|
+
ResultType: 'simple',
|
|
143
|
+
});
|
|
144
|
+
if (!people.Success) {
|
|
145
|
+
throw new Error(people.ErrorMessage ?? 'Failed to resolve the linked person.');
|
|
146
|
+
}
|
|
147
|
+
const personID = people.Results[0]?.ID;
|
|
148
|
+
if (!personID) {
|
|
149
|
+
return { HasLinkedPerson: false };
|
|
150
|
+
}
|
|
151
|
+
const assignments = await runner.RunView({
|
|
152
|
+
EntityName: BIZAPPS_TASK_ASSIGNMENTS_ENTITY_NAME,
|
|
153
|
+
ExtraFilter: `PersonID = '${EscapeSQLString(personID)}'`,
|
|
154
|
+
Fields: ['TaskID'],
|
|
155
|
+
ResultType: 'simple',
|
|
156
|
+
});
|
|
157
|
+
if (!assignments.Success) {
|
|
158
|
+
throw new Error(assignments.ErrorMessage ?? 'Failed to load task assignments.');
|
|
159
|
+
}
|
|
160
|
+
const assignedTaskIDs = assignments.Results.map((a) => a.TaskID).filter((id) => !!id);
|
|
161
|
+
return { HasLinkedPerson: true, PersonID: personID, Filter: BuildPersonScopedTaskFilter(personID, assignedTaskIDs) };
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* ExtraFilter for `MJ_BizApps_Tasks: Tasks` limiting rows to work the given person created or is assigned to.
|
|
165
|
+
* `assignedTaskIDs` come from `MJ_BizApps_Tasks: Task Assignments` for the same person.
|
|
166
|
+
*/
|
|
167
|
+
export function BuildPersonScopedTaskFilter(personID, assignedTaskIDs) {
|
|
168
|
+
const createdClause = `CreatedByPersonID = '${EscapeSQLString(personID)}'`;
|
|
169
|
+
if (assignedTaskIDs.length === 0) {
|
|
170
|
+
return createdClause;
|
|
171
|
+
}
|
|
172
|
+
const idList = assignedTaskIDs.map((id) => `'${EscapeSQLString(id)}'`).join(', ');
|
|
173
|
+
return `${createdClause} OR ID IN (${idList})`;
|
|
174
|
+
}
|
|
175
|
+
export function FormatTaskMetricProgress(task) {
|
|
176
|
+
if (task.TargetValue == null && task.CurrentValue == null) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
const unit = task.UnitOfMeasure ? ` ${task.UnitOfMeasure}` : '';
|
|
180
|
+
const current = task.CurrentValue ?? task.BaselineValue ?? 0;
|
|
181
|
+
if (task.TargetValue != null) {
|
|
182
|
+
return `${current}${unit} / ${task.TargetValue}${unit}`;
|
|
183
|
+
}
|
|
184
|
+
return `${current}${unit}`;
|
|
185
|
+
}
|
|
186
|
+
export function CalculateChiefOfStaffMetrics(tasks, routines, requests, now = new Date()) {
|
|
187
|
+
const subtasksByParent = GroupByUUID(tasks.filter((t) => !!t.ParentID), (t) => t.ParentID);
|
|
188
|
+
const priorityTasks = [];
|
|
189
|
+
for (const task of tasks) {
|
|
190
|
+
const hasChildren = subtasksByParent.Has(task.ID);
|
|
191
|
+
if (!task.ParentID && (IsTaskPriorityObjective(task) || hasChildren)) {
|
|
192
|
+
priorityTasks.push(task);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Only qualifying objectives are shown; an empty list renders the tab's empty state rather than unrelated root tasks.
|
|
196
|
+
const rootsToDisplay = priorityTasks;
|
|
197
|
+
let onTrackCount = 0;
|
|
198
|
+
let atRiskCount = 0;
|
|
199
|
+
let offTrackCount = 0;
|
|
200
|
+
let completedPriorityCount = 0;
|
|
201
|
+
let confidenceSum = 0;
|
|
202
|
+
let confidenceCount = 0;
|
|
203
|
+
let progressSum = 0;
|
|
204
|
+
const priorityCards = rootsToDisplay.map((root) => {
|
|
205
|
+
const children = subtasksByParent.Get(root.ID) ?? [];
|
|
206
|
+
const completedChildren = children.filter((c) => c.Status === 'Completed' || c.Status === 'Done' || (c.PercentComplete ?? 0) >= 100).length;
|
|
207
|
+
const metricPercent = ComputeTaskMetricPercent(root);
|
|
208
|
+
const rawPercent = metricPercent !== null
|
|
209
|
+
? metricPercent
|
|
210
|
+
: typeof root.PercentComplete === 'number' && root.PercentComplete > 0
|
|
211
|
+
? root.PercentComplete
|
|
212
|
+
: children.length > 0
|
|
213
|
+
? Math.round((completedChildren / children.length) * 100)
|
|
214
|
+
: root.Status === 'Completed' || root.Status === 'Done'
|
|
215
|
+
? 100
|
|
216
|
+
: 0;
|
|
217
|
+
const effectivePercent = Math.max(0, Math.min(100, rawPercent));
|
|
218
|
+
const effectiveHealth = NormalizeTaskHealth(root);
|
|
219
|
+
if (effectiveHealth === 'OnTrack')
|
|
220
|
+
onTrackCount++;
|
|
221
|
+
else if (effectiveHealth === 'AtRisk')
|
|
222
|
+
atRiskCount++;
|
|
223
|
+
else if (effectiveHealth === 'OffTrack')
|
|
224
|
+
offTrackCount++;
|
|
225
|
+
else if (effectiveHealth === 'Completed')
|
|
226
|
+
completedPriorityCount++;
|
|
227
|
+
if (typeof root.ConfidenceScore === 'number' && Number.isFinite(root.ConfidenceScore)) {
|
|
228
|
+
confidenceSum += root.ConfidenceScore;
|
|
229
|
+
confidenceCount++;
|
|
230
|
+
}
|
|
231
|
+
progressSum += effectivePercent;
|
|
232
|
+
const dueDate = ParseOptionalDate(root.DueAt);
|
|
233
|
+
const isOverdue = dueDate !== null &&
|
|
234
|
+
dueDate.getTime() < now.getTime() &&
|
|
235
|
+
effectiveHealth !== 'Completed';
|
|
236
|
+
return {
|
|
237
|
+
Task: root,
|
|
238
|
+
Subtasks: children,
|
|
239
|
+
CompletedSubtaskCount: completedChildren,
|
|
240
|
+
EffectivePercentComplete: effectivePercent,
|
|
241
|
+
EffectiveHealth: effectiveHealth,
|
|
242
|
+
MetricProgressLabel: FormatTaskMetricProgress(root),
|
|
243
|
+
IsOverdue: isOverdue,
|
|
244
|
+
};
|
|
245
|
+
});
|
|
246
|
+
const pendingRequests = requests.filter((r) => r.Status === 'Requested' && IsApprovalRequest(r));
|
|
247
|
+
const highPriorityPending = pendingRequests.filter((r) => r.Priority >= 51);
|
|
248
|
+
const activeWakeRoutines = routines.filter((r) => r.Status === 'Active');
|
|
249
|
+
let nextScheduledWakeAt = null;
|
|
250
|
+
for (const routine of activeWakeRoutines) {
|
|
251
|
+
const nextRun = ParseOptionalDate(routine.NextRunAt);
|
|
252
|
+
if (nextRun && (!nextScheduledWakeAt || nextRun.getTime() < nextScheduledWakeAt.getTime())) {
|
|
253
|
+
nextScheduledWakeAt = nextRun;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
const totalSubtasks = tasks.filter((t) => !!t.ParentID).length;
|
|
257
|
+
return {
|
|
258
|
+
TotalTaskCount: tasks.length,
|
|
259
|
+
PriorityObjectiveCount: priorityCards.length,
|
|
260
|
+
SubtaskCount: totalSubtasks,
|
|
261
|
+
OnTrackCount: onTrackCount,
|
|
262
|
+
AtRiskCount: atRiskCount,
|
|
263
|
+
OffTrackCount: offTrackCount,
|
|
264
|
+
CompletedPriorityCount: completedPriorityCount,
|
|
265
|
+
AverageConfidenceScore: confidenceCount > 0 ? Math.round((confidenceSum / confidenceCount) * 10) / 10 : null,
|
|
266
|
+
AveragePriorityProgress: priorityCards.length > 0 ? Math.round(progressSum / priorityCards.length) : 0,
|
|
267
|
+
PendingApprovalCount: pendingRequests.length,
|
|
268
|
+
HighPriorityPendingCount: highPriorityPending.length,
|
|
269
|
+
ActiveWakeRoutineCount: activeWakeRoutines.length,
|
|
270
|
+
NextScheduledWakeAt: nextScheduledWakeAt,
|
|
271
|
+
PriorityCards: priorityCards,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
export function BuildChiefOfStaffAgentContext(input) {
|
|
275
|
+
const priorityNames = input.Metrics.PriorityCards.map((c) => c.Task.Name).filter((n) => !!n);
|
|
276
|
+
const boundedPriorityNames = BoundNameList(priorityNames, AGENT_CONTEXT_NAME_LIST_CAP);
|
|
277
|
+
const routineNames = input.Routines.map((r) => `${r.Name} (${r.Status})`).filter((n) => !!n);
|
|
278
|
+
const boundedRoutineNames = BoundNameList(routineNames, AGENT_CONTEXT_NAME_LIST_CAP);
|
|
279
|
+
const context = {
|
|
280
|
+
Surface: 'ChiefOfStaffDashboard',
|
|
281
|
+
ActiveTab: input.ActiveTab,
|
|
282
|
+
SearchText: input.SearchText,
|
|
283
|
+
HealthFilter: input.HealthFilter,
|
|
284
|
+
PriorityObjectiveCount: input.Metrics.PriorityObjectiveCount,
|
|
285
|
+
SubtaskCount: input.Metrics.SubtaskCount,
|
|
286
|
+
OnTrackCount: input.Metrics.OnTrackCount,
|
|
287
|
+
AtRiskCount: input.Metrics.AtRiskCount,
|
|
288
|
+
OffTrackCount: input.Metrics.OffTrackCount,
|
|
289
|
+
CompletedPriorityCount: input.Metrics.CompletedPriorityCount,
|
|
290
|
+
AveragePriorityProgressPercent: input.Metrics.AveragePriorityProgress,
|
|
291
|
+
PendingApprovalCount: input.Metrics.PendingApprovalCount,
|
|
292
|
+
HighPriorityPendingCount: input.Metrics.HighPriorityPendingCount,
|
|
293
|
+
ActiveWakeRoutineCount: input.Metrics.ActiveWakeRoutineCount,
|
|
294
|
+
NextScheduledWakeAt: input.Metrics.NextScheduledWakeAt
|
|
295
|
+
? input.Metrics.NextScheduledWakeAt.toISOString()
|
|
296
|
+
: null,
|
|
297
|
+
GovernanceSummary: {
|
|
298
|
+
DisplayName: input.Governance.DisplayName,
|
|
299
|
+
Status: input.Governance.Status,
|
|
300
|
+
OnboardingStatus: input.Governance.OnboardingStatus,
|
|
301
|
+
CoordinationMode: input.Governance.CoordinationMode,
|
|
302
|
+
DefaultDataAccessMode: input.Governance.DefaultDataAccessMode,
|
|
303
|
+
EmailChannelMode: input.Governance.EmailChannelMode,
|
|
304
|
+
CalendarChannelMode: input.Governance.CalendarChannelMode,
|
|
305
|
+
PhoneChannelMode: input.Governance.PhoneChannelMode,
|
|
306
|
+
MessagingChannelMode: input.Governance.MessagingChannelMode,
|
|
307
|
+
AllowInterAgentCoordination: input.Governance.AllowInterAgentCoordination,
|
|
308
|
+
RequireApprovalForExternalComms: input.Governance.RequireApprovalForExternalComms,
|
|
309
|
+
RequireApprovalForFinancials: input.Governance.RequireApprovalForFinancials,
|
|
310
|
+
RequireApprovalForDestructiveActions: input.Governance.RequireApprovalForDestructiveActions,
|
|
311
|
+
AutoApproveAmountThreshold: input.Governance.AutoApproveAmountThreshold,
|
|
312
|
+
},
|
|
313
|
+
VisiblePriorityObjectiveNames: boundedPriorityNames,
|
|
314
|
+
VisibleWakeRoutineNames: boundedRoutineNames,
|
|
315
|
+
};
|
|
316
|
+
if (priorityNames.length > boundedPriorityNames.length) {
|
|
317
|
+
context['VisiblePriorityObjectiveNamesTruncated'] = true;
|
|
318
|
+
context['VisiblePriorityObjectiveNamesTotal'] = priorityNames.length;
|
|
319
|
+
}
|
|
320
|
+
return context;
|
|
321
|
+
}
|
|
322
|
+
export function ValidateChiefOfStaffTabParam(raw) {
|
|
323
|
+
return ValidateEnumParam(raw, VALID_CHIEF_OF_STAFF_TABS, 'tab');
|
|
324
|
+
}
|
|
325
|
+
export function ValidateHealthFilterParam(raw) {
|
|
326
|
+
return ValidateEnumParam(raw, VALID_HEALTH_FILTERS, 'health');
|
|
327
|
+
}
|
|
328
|
+
export function ValidateSearchQueryParam(raw) {
|
|
329
|
+
return ValidateStringParam(raw, 'query');
|
|
330
|
+
}
|
|
331
|
+
export function ResolvePriorityObjectiveByIDOrName(cards, rawRef) {
|
|
332
|
+
if (typeof rawRef !== 'string' || rawRef.trim().length === 0) {
|
|
333
|
+
return {
|
|
334
|
+
ok: false,
|
|
335
|
+
error: `Provide a priority objective ID or name. ${availableObjectiveNames(cards)}`,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const ref = rawRef.trim();
|
|
339
|
+
const byId = cards.find((c) => UUIDsEqual(c.Task.ID, ref));
|
|
340
|
+
if (byId) {
|
|
341
|
+
return { ok: true, value: byId };
|
|
342
|
+
}
|
|
343
|
+
const byName = cards.find((c) => c.Task.Name.trim().toLowerCase() === ref.toLowerCase());
|
|
344
|
+
if (byName) {
|
|
345
|
+
return { ok: true, value: byName };
|
|
346
|
+
}
|
|
347
|
+
const partial = cards.filter((c) => c.Task.Name.toLowerCase().includes(ref.toLowerCase()));
|
|
348
|
+
if (partial.length === 1) {
|
|
349
|
+
return { ok: true, value: partial[0] };
|
|
350
|
+
}
|
|
351
|
+
if (partial.length > 1) {
|
|
352
|
+
const names = partial
|
|
353
|
+
.slice(0, AGENT_CONTEXT_NAME_LIST_CAP)
|
|
354
|
+
.map((c) => c.Task.Name)
|
|
355
|
+
.join(', ');
|
|
356
|
+
return {
|
|
357
|
+
ok: false,
|
|
358
|
+
error: `'${ref}' matches multiple priority objectives: ${names}. Be more specific.`,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
ok: false,
|
|
363
|
+
error: `No priority objective matches '${ref}'. ${availableObjectiveNames(cards)}`,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function availableObjectiveNames(cards) {
|
|
367
|
+
if (cards.length === 0) {
|
|
368
|
+
return 'There are no priority objectives loaded.';
|
|
369
|
+
}
|
|
370
|
+
const names = cards.slice(0, AGENT_CONTEXT_NAME_LIST_CAP).map((c) => c.Task.Name);
|
|
371
|
+
const suffix = cards.length > AGENT_CONTEXT_NAME_LIST_CAP ? ', …' : '';
|
|
372
|
+
return `Available priority objectives: ${names.join(', ')}${suffix}`;
|
|
373
|
+
}
|
|
374
|
+
//# sourceMappingURL=chief-of-staff-agent-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chief-of-staff-agent-context.js","sourceRoot":"","sources":["../../src/ChiefOfStaff/chief-of-staff-agent-context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure, unit-testable helpers for the \"My Chief of Staff\" Executive Cockpit's\n * agent context + client tools.\n *\n * 🚨 SAFETY BOUNDARY 🚨\n * The Chief of Staff Cockpit exposes ONLY navigation / tab-switch / filter / search /\n * refresh / detail-view tools to the co-agent. DELIBERATELY NOT exposed as client tools\n * (mutations stay human-driven in the UI):\n * - Approving or rejecting `MJ: AI Agent Requests`\n * - Modifying or saving `MJ: AI Agent User Policies` governance toggles / thresholds\n * - Triggering \"Wake Now\" or pausing/resuming `MJ: User Routines`\n *\n * Published context exposes only aggregate counts, active tab/filter state, governance\n * mode summaries, and bounded display names (capped at 25) — never raw request payloads,\n * custom instructions overrides, or private message content.\n */\n\nimport type {\n MJAIAgentUserPolicyEntity,\n MJUserRoutineEntity,\n MJAIAgentRequestEntity,\n} from '@memberjunction/core-entities';\nimport { CompositeKey, type EntityInfo, type RunViewParams } from '@memberjunction/core';\nimport { EscapeSQLString, GroupByUUID, UUIDsEqual } from '@memberjunction/global';\nimport {\n AGENT_CONTEXT_NAME_LIST_CAP,\n BoundNameList,\n ValidateEnumParam,\n ValidateStringParam,\n type AgentToolResult,\n} from '../shared/agent-tool-validation';\n\n/**\n * The cockpit serves one agent, identified by its metadata name. The id is resolved at runtime\n * through `AIEngineBase.GetAgentByName`, never hardcoded.\n */\nexport const CHIEF_OF_STAFF_AGENT_NAME = 'Chief of Staff';\n\nexport type ChiefOfStaffTab = 'overview' | 'priorities' | 'approvals-wakes' | 'governance';\nexport const VALID_CHIEF_OF_STAFF_TABS: readonly ChiefOfStaffTab[] = [\n 'overview',\n 'priorities',\n 'approvals-wakes',\n 'governance',\n] as const;\n\nexport type TaskHealthStatus = 'OnTrack' | 'AtRisk' | 'OffTrack' | 'Completed' | 'Paused';\nexport type HealthFilter = 'all' | TaskHealthStatus;\nexport const VALID_HEALTH_FILTERS: readonly HealthFilter[] = [\n 'all',\n 'OnTrack',\n 'AtRisk',\n 'OffTrack',\n 'Completed',\n 'Paused',\n] as const;\n\nexport type PolicyStatusValue = MJAIAgentUserPolicyEntity['Status'];\nexport type PolicyCoordinationModeValue = MJAIAgentUserPolicyEntity['CoordinationMode'];\nexport type PolicyDataAccessModeValue = MJAIAgentUserPolicyEntity['DefaultDataAccessMode'];\nexport type PolicyEmailChannelModeValue = MJAIAgentUserPolicyEntity['EmailChannelMode'];\nexport type PolicyCalendarChannelModeValue = MJAIAgentUserPolicyEntity['CalendarChannelMode'];\nexport type PolicyPhoneChannelModeValue = MJAIAgentUserPolicyEntity['PhoneChannelMode'];\nexport type PolicyMessagingChannelModeValue = MJAIAgentUserPolicyEntity['MessagingChannelMode'];\nexport type RoutineStatusValue = MJUserRoutineEntity['Status'];\nexport type RequestStatusValue = MJAIAgentRequestEntity['Status'];\n\n/**\n * Projection shape for rows returned from `MJ_BizApps_Tasks: Tasks` (`[__mj_BizAppsTasks].[vwTasks]`).\n */\nexport interface BizAppsTaskRecordLike {\n ID: string;\n ParentID: string | null;\n Name: string;\n Description: string | null;\n Status: string;\n Priority: string | null;\n IsPriority: boolean | number | null;\n HealthStatus: TaskHealthStatus | null;\n ConfidenceScore: number | null;\n PercentComplete: number | null;\n CheckInCadence: string | null;\n PlanningPeriod: string | null;\n BaselineValue: number | null;\n TargetValue: number | null;\n CurrentValue: number | null;\n UnitOfMeasure: string | null;\n MetricDirection: string | null;\n DueAt: Date | string | null;\n LastCheckInAt: Date | string | null;\n NextCheckInDueAt: Date | string | null;\n TypeID?: string | null;\n Type?: string | null;\n TaskType?: string | null;\n}\n\n/**\n * Grouped priority objective card with its child milestones/tasks and computed progress.\n */\nexport interface PriorityObjectiveCardViewModel {\n Task: BizAppsTaskRecordLike;\n Subtasks: BizAppsTaskRecordLike[];\n CompletedSubtaskCount: number;\n EffectivePercentComplete: number;\n EffectiveHealth: TaskHealthStatus;\n MetricProgressLabel: string | null;\n IsOverdue: boolean;\n}\n\nexport interface RoutineSummaryItem {\n ID: string;\n Name: string;\n Status: RoutineStatusValue;\n ScheduleMode: MJUserRoutineEntity['ScheduleMode'];\n CronExpression: string | null;\n NextRunAt: Date | string | null;\n LastRunAt: Date | string | null;\n LastRunStatus: MJUserRoutineEntity['LastRunStatus'];\n}\n\nexport interface RequestSummaryItem {\n ID: string;\n Request: string;\n Status: RequestStatusValue;\n Priority: number;\n RequestedAt: Date | string;\n ExpiresAt: Date | string | null;\n RequestType?: MJAIAgentRequestEntity['RequestType'];\n RequestTypeID?: MJAIAgentRequestEntity['RequestTypeID'];\n}\n\nexport interface PolicyGovernanceSummary {\n HasPolicyRecord: boolean;\n DisplayName: string;\n Status: PolicyStatusValue;\n OnboardingStatus: MJAIAgentUserPolicyEntity['OnboardingStatus'];\n CoordinationMode: PolicyCoordinationModeValue;\n DefaultDataAccessMode: PolicyDataAccessModeValue;\n EmailChannelMode: PolicyEmailChannelModeValue;\n CalendarChannelMode: PolicyCalendarChannelModeValue;\n PhoneChannelMode: PolicyPhoneChannelModeValue;\n MessagingChannelMode: PolicyMessagingChannelModeValue;\n AllowInterAgentCoordination: boolean;\n RequireApprovalForExternalComms: boolean;\n RequireApprovalForFinancials: boolean;\n RequireApprovalForDestructiveActions: boolean;\n AutoApproveAmountThreshold: number | null;\n}\n\nexport interface ChiefOfStaffMetrics {\n TotalTaskCount: number;\n PriorityObjectiveCount: number;\n SubtaskCount: number;\n OnTrackCount: number;\n AtRiskCount: number;\n OffTrackCount: number;\n CompletedPriorityCount: number;\n AverageConfidenceScore: number | null;\n AveragePriorityProgress: number;\n PendingApprovalCount: number;\n HighPriorityPendingCount: number;\n ActiveWakeRoutineCount: number;\n NextScheduledWakeAt: Date | null;\n PriorityCards: PriorityObjectiveCardViewModel[];\n}\n\nexport interface ChiefOfStaffAgentContextInput {\n ActiveTab: ChiefOfStaffTab;\n SearchText: string;\n HealthFilter: HealthFilter;\n Metrics: ChiefOfStaffMetrics;\n Governance: PolicyGovernanceSummary;\n Routines: readonly RoutineSummaryItem[];\n PendingRequests: readonly RequestSummaryItem[];\n}\n\nexport type AgentContextScalar = string | number | boolean | null;\nexport type AgentContextRecord = Record<\n string,\n AgentContextScalar | string[] | Record<string, AgentContextScalar>\n>;\n\n/**\n * Returns `true` when an `MJ: AI Agent Requests` row represents an actionable approval or\n * review request for the Executive Cockpit's Pending Approvals queue, and `false` when it\n * is a conversational `Information` turn created by `BaseAgent` when ending a chat turn.\n */\nexport function IsApprovalRequest(req: {\n RequestType?: MJAIAgentRequestEntity['RequestType'] | undefined;\n RequestTypeID?: MJAIAgentRequestEntity['RequestTypeID'] | undefined;\n}): boolean {\n // The RequestType virtual field carries the type name; classify on it alone.\n const typeName = req.RequestType?.trim().toLowerCase() ?? '';\n return typeName !== 'information';\n}\n\nexport function ParseOptionalDate(val: Date | string | null | undefined): Date | null {\n if (!val) {\n return null;\n }\n if (val instanceof Date) {\n return isNaN(val.getTime()) ? null : val;\n }\n const parsed = new Date(val);\n return isNaN(parsed.getTime()) ? null : parsed;\n}\n\n/**\n * Builds the primary key of a BizApps task from the entity's own primary key column(s) and the\n * in-memory row. Tasks is an OpenApp entity, so neither the column name nor the column count is\n * assumed; the same key feeds `OpenEntityRecord` and the `PrimaryKey` parameter of `Update Record`.\n */\nexport function BuildTaskRecordKey(entityInfo: EntityInfo, task: BizAppsTaskRecordLike): CompositeKey {\n return CompositeKey.FromEntityRecord(entityInfo, { ...task });\n}\n\nexport function IsTaskPriorityObjective(task: BizAppsTaskRecordLike): boolean {\n if (task.IsPriority === true || task.IsPriority === 1) {\n return true;\n }\n const typeLabel = (task.Type ?? task.TaskType ?? '').toLowerCase();\n if (\n typeLabel.includes('priority') ||\n typeLabel.includes('objective') ||\n typeLabel.includes('okr')\n ) {\n return true;\n }\n return task.ParentID == null && (task.HealthStatus != null || task.PlanningPeriod != null);\n}\n\nexport function NormalizeTaskHealth(task: BizAppsTaskRecordLike): TaskHealthStatus {\n if (task.Status === 'Completed' || task.Status === 'Done' || task.HealthStatus === 'Completed') {\n return 'Completed';\n }\n if (task.HealthStatus === 'AtRisk' || task.HealthStatus === 'OffTrack' || task.HealthStatus === 'Paused') {\n return task.HealthStatus;\n }\n return 'OnTrack';\n}\n\n/**\n * Percent progress from `BaselineValue` toward `TargetValue`, clamped to 0-100.\n * Honors `MetricDirection` implicitly: a Down target (target < baseline) measures reduction.\n * Returns null when there is no target or the target equals the baseline (no measurable span).\n */\nexport function ComputeTaskMetricPercent(task: BizAppsTaskRecordLike): number | null {\n if (task.TargetValue == null) {\n return null;\n }\n const baseline = task.BaselineValue ?? 0;\n const span = task.TargetValue - baseline;\n if (span === 0) {\n return null;\n }\n const current = task.CurrentValue ?? baseline;\n const raw = ((current - baseline) / span) * 100;\n return Math.max(0, Math.min(100, Math.round(raw)));\n}\n\n/** ExtraFilters for the cockpit's three core-entity queries. Every clause is bound to the current user: the cockpit never shows another user's Chief of Staff data. */\nexport interface CockpitScopeFilters {\n Policy: string;\n Routines: string;\n Requests: string;\n}\n\nexport function BuildCockpitScopeFilters(currentUserId: string, chiefOfStaffAgentId: string): CockpitScopeFilters {\n const user = EscapeSQLString(currentUserId);\n const agent = EscapeSQLString(chiefOfStaffAgentId);\n return {\n Policy: `AgentID = '${agent}' AND UserID = '${user}'`,\n Routines: `UserID = '${user}' AND (RoutineType = 'AgentWake' OR TargetID = '${agent}')`,\n Requests: `AgentID = '${agent}' AND RequestForUserID = '${user}' AND (RequestType IS NULL OR RequestType <> 'Information')`,\n };\n}\n\n/** OpenApp entity holding the person linked to the signed-in MJ user (`LinkedUserID`). */\nexport const BIZAPPS_PEOPLE_ENTITY_NAME = 'MJ_BizApps_Common: People';\n/** OpenApp entity linking tasks to the people assigned to them. */\nexport const BIZAPPS_TASK_ASSIGNMENTS_ENTITY_NAME = 'MJ_BizApps_Tasks: Task Assignments';\n\n/** CSS modifier for a task priority badge, keyed by the Tasks `Priority` value list (Critical/High/Medium/Low). */\nexport function GetTaskPriorityClass(priority: string | null): string {\n switch ((priority ?? '').toLowerCase()) {\n case 'critical':\n return 'priority-critical';\n case 'high':\n return 'priority-high';\n case 'low':\n return 'priority-low';\n default:\n return 'priority-normal';\n }\n}\n\n/** Minimal RunView surface the task-scope resolver needs; `RunView` from @memberjunction/core satisfies it. */\nexport interface TaskScopeQueryRunner {\n RunView<T>(params: RunViewParams): Promise<{ Success: boolean; Results: T[]; ErrorMessage?: string }>;\n}\n\nexport type PersonTaskScope =\n | { HasLinkedPerson: false }\n | { HasLinkedPerson: true; PersonID: string; Filter: string };\n\n/**\n * Resolve the BizApps person linked to `currentUserId` and the filter that limits the Tasks query to work\n * that person created or is assigned to. Throws when either lookup fails so the caller can show the error.\n */\nexport async function ResolvePersonTaskScope(\n runner: TaskScopeQueryRunner,\n currentUserId: string,\n): Promise<PersonTaskScope> {\n const people = await runner.RunView<{ ID: string }>({\n EntityName: BIZAPPS_PEOPLE_ENTITY_NAME,\n ExtraFilter: `LinkedUserID = '${EscapeSQLString(currentUserId)}'`,\n Fields: ['ID'],\n MaxRows: 1,\n ResultType: 'simple',\n });\n if (!people.Success) {\n throw new Error(people.ErrorMessage ?? 'Failed to resolve the linked person.');\n }\n const personID = people.Results[0]?.ID;\n if (!personID) {\n return { HasLinkedPerson: false };\n }\n const assignments = await runner.RunView<{ TaskID: string }>({\n EntityName: BIZAPPS_TASK_ASSIGNMENTS_ENTITY_NAME,\n ExtraFilter: `PersonID = '${EscapeSQLString(personID)}'`,\n Fields: ['TaskID'],\n ResultType: 'simple',\n });\n if (!assignments.Success) {\n throw new Error(assignments.ErrorMessage ?? 'Failed to load task assignments.');\n }\n const assignedTaskIDs = assignments.Results.map((a) => a.TaskID).filter((id) => !!id);\n return { HasLinkedPerson: true, PersonID: personID, Filter: BuildPersonScopedTaskFilter(personID, assignedTaskIDs) };\n}\n\n/**\n * ExtraFilter for `MJ_BizApps_Tasks: Tasks` limiting rows to work the given person created or is assigned to.\n * `assignedTaskIDs` come from `MJ_BizApps_Tasks: Task Assignments` for the same person.\n */\nexport function BuildPersonScopedTaskFilter(personID: string, assignedTaskIDs: readonly string[]): string {\n const createdClause = `CreatedByPersonID = '${EscapeSQLString(personID)}'`;\n if (assignedTaskIDs.length === 0) {\n return createdClause;\n }\n const idList = assignedTaskIDs.map((id) => `'${EscapeSQLString(id)}'`).join(', ');\n return `${createdClause} OR ID IN (${idList})`;\n}\n\nexport function FormatTaskMetricProgress(task: BizAppsTaskRecordLike): string | null {\n if (task.TargetValue == null && task.CurrentValue == null) {\n return null;\n }\n const unit = task.UnitOfMeasure ? ` ${task.UnitOfMeasure}` : '';\n const current = task.CurrentValue ?? task.BaselineValue ?? 0;\n if (task.TargetValue != null) {\n return `${current}${unit} / ${task.TargetValue}${unit}`;\n }\n return `${current}${unit}`;\n}\n\nexport function CalculateChiefOfStaffMetrics(\n tasks: readonly BizAppsTaskRecordLike[],\n routines: readonly RoutineSummaryItem[],\n requests: readonly RequestSummaryItem[],\n now: Date = new Date(),\n): ChiefOfStaffMetrics {\n const subtasksByParent = GroupByUUID(\n tasks.filter((t) => !!t.ParentID),\n (t) => t.ParentID,\n );\n const priorityTasks: BizAppsTaskRecordLike[] = [];\n\n for (const task of tasks) {\n const hasChildren = subtasksByParent.Has(task.ID);\n if (!task.ParentID && (IsTaskPriorityObjective(task) || hasChildren)) {\n priorityTasks.push(task);\n }\n }\n\n // Only qualifying objectives are shown; an empty list renders the tab's empty state rather than unrelated root tasks.\n const rootsToDisplay = priorityTasks;\n\n let onTrackCount = 0;\n let atRiskCount = 0;\n let offTrackCount = 0;\n let completedPriorityCount = 0;\n let confidenceSum = 0;\n let confidenceCount = 0;\n let progressSum = 0;\n\n const priorityCards: PriorityObjectiveCardViewModel[] = rootsToDisplay.map((root) => {\n const children = subtasksByParent.Get(root.ID) ?? [];\n const completedChildren = children.filter(\n (c) => c.Status === 'Completed' || c.Status === 'Done' || (c.PercentComplete ?? 0) >= 100,\n ).length;\n\n const metricPercent = ComputeTaskMetricPercent(root);\n const rawPercent =\n metricPercent !== null\n ? metricPercent\n : typeof root.PercentComplete === 'number' && root.PercentComplete > 0\n ? root.PercentComplete\n : children.length > 0\n ? Math.round((completedChildren / children.length) * 100)\n : root.Status === 'Completed' || root.Status === 'Done'\n ? 100\n : 0;\n const effectivePercent = Math.max(0, Math.min(100, rawPercent));\n const effectiveHealth = NormalizeTaskHealth(root);\n\n if (effectiveHealth === 'OnTrack') onTrackCount++;\n else if (effectiveHealth === 'AtRisk') atRiskCount++;\n else if (effectiveHealth === 'OffTrack') offTrackCount++;\n else if (effectiveHealth === 'Completed') completedPriorityCount++;\n\n if (typeof root.ConfidenceScore === 'number' && Number.isFinite(root.ConfidenceScore)) {\n confidenceSum += root.ConfidenceScore;\n confidenceCount++;\n }\n progressSum += effectivePercent;\n\n const dueDate = ParseOptionalDate(root.DueAt);\n const isOverdue =\n dueDate !== null &&\n dueDate.getTime() < now.getTime() &&\n effectiveHealth !== 'Completed';\n\n return {\n Task: root,\n Subtasks: children,\n CompletedSubtaskCount: completedChildren,\n EffectivePercentComplete: effectivePercent,\n EffectiveHealth: effectiveHealth,\n MetricProgressLabel: FormatTaskMetricProgress(root),\n IsOverdue: isOverdue,\n };\n });\n\n const pendingRequests = requests.filter(\n (r) => r.Status === 'Requested' && IsApprovalRequest(r),\n );\n const highPriorityPending = pendingRequests.filter((r) => r.Priority >= 51);\n\n const activeWakeRoutines = routines.filter((r) => r.Status === 'Active');\n let nextScheduledWakeAt: Date | null = null;\n for (const routine of activeWakeRoutines) {\n const nextRun = ParseOptionalDate(routine.NextRunAt);\n if (nextRun && (!nextScheduledWakeAt || nextRun.getTime() < nextScheduledWakeAt.getTime())) {\n nextScheduledWakeAt = nextRun;\n }\n }\n\n const totalSubtasks = tasks.filter((t) => !!t.ParentID).length;\n\n return {\n TotalTaskCount: tasks.length,\n PriorityObjectiveCount: priorityCards.length,\n SubtaskCount: totalSubtasks,\n OnTrackCount: onTrackCount,\n AtRiskCount: atRiskCount,\n OffTrackCount: offTrackCount,\n CompletedPriorityCount: completedPriorityCount,\n AverageConfidenceScore:\n confidenceCount > 0 ? Math.round((confidenceSum / confidenceCount) * 10) / 10 : null,\n AveragePriorityProgress:\n priorityCards.length > 0 ? Math.round(progressSum / priorityCards.length) : 0,\n PendingApprovalCount: pendingRequests.length,\n HighPriorityPendingCount: highPriorityPending.length,\n ActiveWakeRoutineCount: activeWakeRoutines.length,\n NextScheduledWakeAt: nextScheduledWakeAt,\n PriorityCards: priorityCards,\n };\n}\n\nexport function BuildChiefOfStaffAgentContext(\n input: ChiefOfStaffAgentContextInput,\n): AgentContextRecord {\n const priorityNames = input.Metrics.PriorityCards.map((c) => c.Task.Name).filter((n) => !!n);\n const boundedPriorityNames = BoundNameList(priorityNames, AGENT_CONTEXT_NAME_LIST_CAP);\n\n const routineNames = input.Routines.map((r) => `${r.Name} (${r.Status})`).filter((n) => !!n);\n const boundedRoutineNames = BoundNameList(routineNames, AGENT_CONTEXT_NAME_LIST_CAP);\n\n const context: AgentContextRecord = {\n Surface: 'ChiefOfStaffDashboard',\n ActiveTab: input.ActiveTab,\n SearchText: input.SearchText,\n HealthFilter: input.HealthFilter,\n PriorityObjectiveCount: input.Metrics.PriorityObjectiveCount,\n SubtaskCount: input.Metrics.SubtaskCount,\n OnTrackCount: input.Metrics.OnTrackCount,\n AtRiskCount: input.Metrics.AtRiskCount,\n OffTrackCount: input.Metrics.OffTrackCount,\n CompletedPriorityCount: input.Metrics.CompletedPriorityCount,\n AveragePriorityProgressPercent: input.Metrics.AveragePriorityProgress,\n PendingApprovalCount: input.Metrics.PendingApprovalCount,\n HighPriorityPendingCount: input.Metrics.HighPriorityPendingCount,\n ActiveWakeRoutineCount: input.Metrics.ActiveWakeRoutineCount,\n NextScheduledWakeAt: input.Metrics.NextScheduledWakeAt\n ? input.Metrics.NextScheduledWakeAt.toISOString()\n : null,\n GovernanceSummary: {\n DisplayName: input.Governance.DisplayName,\n Status: input.Governance.Status,\n OnboardingStatus: input.Governance.OnboardingStatus,\n CoordinationMode: input.Governance.CoordinationMode,\n DefaultDataAccessMode: input.Governance.DefaultDataAccessMode,\n EmailChannelMode: input.Governance.EmailChannelMode,\n CalendarChannelMode: input.Governance.CalendarChannelMode,\n PhoneChannelMode: input.Governance.PhoneChannelMode,\n MessagingChannelMode: input.Governance.MessagingChannelMode,\n AllowInterAgentCoordination: input.Governance.AllowInterAgentCoordination,\n RequireApprovalForExternalComms: input.Governance.RequireApprovalForExternalComms,\n RequireApprovalForFinancials: input.Governance.RequireApprovalForFinancials,\n RequireApprovalForDestructiveActions:\n input.Governance.RequireApprovalForDestructiveActions,\n AutoApproveAmountThreshold: input.Governance.AutoApproveAmountThreshold,\n },\n VisiblePriorityObjectiveNames: boundedPriorityNames,\n VisibleWakeRoutineNames: boundedRoutineNames,\n };\n\n if (priorityNames.length > boundedPriorityNames.length) {\n context['VisiblePriorityObjectiveNamesTruncated'] = true;\n context['VisiblePriorityObjectiveNamesTotal'] = priorityNames.length;\n }\n\n return context;\n}\n\nexport function ValidateChiefOfStaffTabParam(\n raw: string | number | boolean | null | undefined,\n): { ok: true; value: ChiefOfStaffTab } | { ok: false; result: AgentToolResult } {\n return ValidateEnumParam(raw, VALID_CHIEF_OF_STAFF_TABS, 'tab');\n}\n\nexport function ValidateHealthFilterParam(\n raw: string | number | boolean | null | undefined,\n): { ok: true; value: HealthFilter } | { ok: false; result: AgentToolResult } {\n return ValidateEnumParam(raw, VALID_HEALTH_FILTERS, 'health');\n}\n\nexport function ValidateSearchQueryParam(\n raw: string | number | boolean | null | undefined,\n): { ok: true; value: string } | { ok: false; result: AgentToolResult } {\n return ValidateStringParam(raw, 'query');\n}\n\nexport function ResolvePriorityObjectiveByIDOrName(\n cards: readonly PriorityObjectiveCardViewModel[],\n rawRef: string | number | boolean | null | undefined,\n): { ok: true; value: PriorityObjectiveCardViewModel } | { ok: false; error: string } {\n if (typeof rawRef !== 'string' || rawRef.trim().length === 0) {\n return {\n ok: false,\n error: `Provide a priority objective ID or name. ${availableObjectiveNames(cards)}`,\n };\n }\n const ref = rawRef.trim();\n const byId = cards.find((c) => UUIDsEqual(c.Task.ID, ref));\n if (byId) {\n return { ok: true, value: byId };\n }\n const byName = cards.find((c) => c.Task.Name.trim().toLowerCase() === ref.toLowerCase());\n if (byName) {\n return { ok: true, value: byName };\n }\n const partial = cards.filter((c) => c.Task.Name.toLowerCase().includes(ref.toLowerCase()));\n if (partial.length === 1) {\n return { ok: true, value: partial[0] };\n }\n if (partial.length > 1) {\n const names = partial\n .slice(0, AGENT_CONTEXT_NAME_LIST_CAP)\n .map((c) => c.Task.Name)\n .join(', ');\n return {\n ok: false,\n error: `'${ref}' matches multiple priority objectives: ${names}. Be more specific.`,\n };\n }\n return {\n ok: false,\n error: `No priority objective matches '${ref}'. ${availableObjectiveNames(cards)}`,\n };\n}\n\nfunction availableObjectiveNames(cards: readonly PriorityObjectiveCardViewModel[]): string {\n if (cards.length === 0) {\n return 'There are no priority objectives loaded.';\n }\n const names = cards.slice(0, AGENT_CONTEXT_NAME_LIST_CAP).map((c) => c.Task.Name);\n const suffix = cards.length > AGENT_CONTEXT_NAME_LIST_CAP ? ', …' : '';\n return `Available priority objectives: ${names.join(', ')}${suffix}`;\n}\n"]}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { OnDestroy, OnInit } from '@angular/core';
|
|
2
|
+
import { Subject } from 'rxjs';
|
|
3
|
+
import { MJAIAgentRequestEntity, MJAIAgentUserPolicyEntity, MJUserRoutineEntity, ResourceData } from '@memberjunction/core-entities';
|
|
4
|
+
import { UUIDSet } from '@memberjunction/global';
|
|
5
|
+
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
6
|
+
import { AgentRequestPanelResult } from '@memberjunction/ng-agent-requests';
|
|
7
|
+
import { TabConfig } from '@memberjunction/ng-ui-components';
|
|
8
|
+
import { BizAppsTaskRecordLike, ChiefOfStaffMetrics, ChiefOfStaffTab, HealthFilter, PolicyCalendarChannelModeValue, PolicyCoordinationModeValue, PolicyDataAccessModeValue, PolicyEmailChannelModeValue, PolicyMessagingChannelModeValue, PolicyPhoneChannelModeValue, PolicyStatusValue, PriorityObjectiveCardViewModel, TaskHealthStatus } from './chief-of-staff-agent-context';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
export interface GovernancePolicyDraft {
|
|
11
|
+
DisplayNameOverride: string;
|
|
12
|
+
Status: PolicyStatusValue;
|
|
13
|
+
OnboardingStatus: MJAIAgentUserPolicyEntity['OnboardingStatus'];
|
|
14
|
+
CoordinationMode: PolicyCoordinationModeValue;
|
|
15
|
+
DefaultDataAccessMode: PolicyDataAccessModeValue;
|
|
16
|
+
EmailChannelMode: PolicyEmailChannelModeValue;
|
|
17
|
+
CalendarChannelMode: PolicyCalendarChannelModeValue;
|
|
18
|
+
PhoneChannelMode: PolicyPhoneChannelModeValue;
|
|
19
|
+
MessagingChannelMode: PolicyMessagingChannelModeValue;
|
|
20
|
+
AllowInterAgentCoordination: boolean;
|
|
21
|
+
RequireApprovalForExternalComms: boolean;
|
|
22
|
+
RequireApprovalForFinancials: boolean;
|
|
23
|
+
RequireApprovalForDestructiveActions: boolean;
|
|
24
|
+
AutoApproveAmountThreshold: number | null;
|
|
25
|
+
InstructionsOverride: string;
|
|
26
|
+
}
|
|
27
|
+
export interface TaskQuickEditDraft {
|
|
28
|
+
Status: string;
|
|
29
|
+
HealthStatus: TaskHealthStatus | null;
|
|
30
|
+
PercentComplete: number | null;
|
|
31
|
+
ConfidenceScore: number | null;
|
|
32
|
+
DueAt: string;
|
|
33
|
+
Description: string;
|
|
34
|
+
}
|
|
35
|
+
export declare class ChiefOfStaffDashboardComponent extends BaseResourceComponent implements OnInit, OnDestroy {
|
|
36
|
+
private cdr;
|
|
37
|
+
protected destroy$: Subject<void>;
|
|
38
|
+
private initialParamsApplied;
|
|
39
|
+
IsLoading: boolean;
|
|
40
|
+
IsSavingPolicy: boolean;
|
|
41
|
+
BusyRequestID: string | null;
|
|
42
|
+
BusyRoutineID: string | null;
|
|
43
|
+
FeedbackBanner: {
|
|
44
|
+
Type: 'success' | 'error';
|
|
45
|
+
Message: string;
|
|
46
|
+
} | null;
|
|
47
|
+
ActiveTab: ChiefOfStaffTab;
|
|
48
|
+
SearchText: string;
|
|
49
|
+
HealthFilter: HealthFilter;
|
|
50
|
+
PolicyEntity: MJAIAgentUserPolicyEntity | null;
|
|
51
|
+
DraftPolicy: GovernancePolicyDraft;
|
|
52
|
+
PolicyDirty: boolean;
|
|
53
|
+
Tasks: BizAppsTaskRecordLike[];
|
|
54
|
+
/** False when the signed-in user has no `MJ_BizApps_Common: People` record linked via `LinkedUserID`; the Priorities tab then shows guidance instead of tasks. */
|
|
55
|
+
HasLinkedPerson: boolean;
|
|
56
|
+
Routines: MJUserRoutineEntity[];
|
|
57
|
+
Requests: MJAIAgentRequestEntity[];
|
|
58
|
+
Metrics: ChiefOfStaffMetrics;
|
|
59
|
+
ExpandedPriorityIDs: UUIDSet;
|
|
60
|
+
SelectedRequest: MJAIAgentRequestEntity | null;
|
|
61
|
+
ShowRequestDialog: boolean;
|
|
62
|
+
SelectedTask: BizAppsTaskRecordLike | null;
|
|
63
|
+
ShowTaskDrawer: boolean;
|
|
64
|
+
IsSavingTask: boolean;
|
|
65
|
+
TaskDirty: boolean;
|
|
66
|
+
DraftTaskEdits: TaskQuickEditDraft;
|
|
67
|
+
readonly TaskStatusOptions: readonly string[];
|
|
68
|
+
readonly StatusOptions: readonly PolicyStatusValue[];
|
|
69
|
+
readonly CoordinationModeOptions: readonly {
|
|
70
|
+
Value: PolicyCoordinationModeValue;
|
|
71
|
+
Label: string;
|
|
72
|
+
Description: string;
|
|
73
|
+
}[];
|
|
74
|
+
readonly DataAccessModeOptions: readonly {
|
|
75
|
+
Value: PolicyDataAccessModeValue;
|
|
76
|
+
Label: string;
|
|
77
|
+
}[];
|
|
78
|
+
readonly EmailChannelOptions: readonly {
|
|
79
|
+
Value: PolicyEmailChannelModeValue;
|
|
80
|
+
Label: string;
|
|
81
|
+
}[];
|
|
82
|
+
readonly CalendarChannelOptions: readonly {
|
|
83
|
+
Value: PolicyCalendarChannelModeValue;
|
|
84
|
+
Label: string;
|
|
85
|
+
}[];
|
|
86
|
+
readonly PhoneChannelOptions: readonly {
|
|
87
|
+
Value: PolicyPhoneChannelModeValue;
|
|
88
|
+
Label: string;
|
|
89
|
+
}[];
|
|
90
|
+
readonly MessagingChannelOptions: readonly {
|
|
91
|
+
Value: PolicyMessagingChannelModeValue;
|
|
92
|
+
Label: string;
|
|
93
|
+
}[];
|
|
94
|
+
readonly HealthFilterOptions: readonly {
|
|
95
|
+
Value: HealthFilter;
|
|
96
|
+
Label: string;
|
|
97
|
+
}[];
|
|
98
|
+
get Tabs(): TabConfig[];
|
|
99
|
+
get ChiefOfStaffDisplayName(): string;
|
|
100
|
+
get FilteredPriorityCards(): PriorityObjectiveCardViewModel[];
|
|
101
|
+
get PendingRequests(): MJAIAgentRequestEntity[];
|
|
102
|
+
get RecentResolvedRequests(): MJAIAgentRequestEntity[];
|
|
103
|
+
get FilteredRoutines(): MJUserRoutineEntity[];
|
|
104
|
+
ngOnInit(): Promise<void>;
|
|
105
|
+
ngOnDestroy(): void;
|
|
106
|
+
GetResourceDisplayName(_data: ResourceData): Promise<string>;
|
|
107
|
+
GetResourceIconClass(_data: ResourceData): Promise<string>;
|
|
108
|
+
protected OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void;
|
|
109
|
+
private applyQueryParams;
|
|
110
|
+
private syncQueryParams;
|
|
111
|
+
LoadCockpitData(): Promise<void>;
|
|
112
|
+
private recalculateMetrics;
|
|
113
|
+
private createDefaultDraftPolicy;
|
|
114
|
+
private buildDraftFromEntity;
|
|
115
|
+
private buildGovernanceSummary;
|
|
116
|
+
OnTabChange(tabId: string): void;
|
|
117
|
+
OnSearchChange(value: string): void;
|
|
118
|
+
OnHealthFilterChange(filterVal: HealthFilter): void;
|
|
119
|
+
ClearFilters(): void;
|
|
120
|
+
TogglePriorityExpanded(taskId: string): void;
|
|
121
|
+
IsPriorityExpanded(taskId: string): boolean;
|
|
122
|
+
get CanOpenFullTaskForm(): boolean;
|
|
123
|
+
get SelectedTaskIsObjective(): boolean;
|
|
124
|
+
/** Resolved once per load from the agent's metadata name; null until LoadCockpitData has run. */
|
|
125
|
+
private chiefOfStaffAgentId;
|
|
126
|
+
/**
|
|
127
|
+
* Looks the Chief of Staff agent up by name through the AI engine's cached agents, so the
|
|
128
|
+
* cockpit carries no hardcoded agent id and follows whichever provider it is embedded under.
|
|
129
|
+
*/
|
|
130
|
+
private resolveChiefOfStaffAgentId;
|
|
131
|
+
private get bizAppsTasksEntityInfo();
|
|
132
|
+
/**
|
|
133
|
+
* Builds the primary key for a BizApps task. Tasks is an OpenApp entity, so the key is
|
|
134
|
+
* derived from its metadata rather than assuming a column named `ID`. Returns null (and
|
|
135
|
+
* surfaces an error banner) when the entity is not installed in this environment.
|
|
136
|
+
*/
|
|
137
|
+
private taskRecordKey;
|
|
138
|
+
/** For a task id that is not in the loaded list: the bare value maps onto the entity's first key column. */
|
|
139
|
+
private taskRecordKeyFromId;
|
|
140
|
+
private requireTasksEntityInfo;
|
|
141
|
+
get SelectedTaskSubtasks(): BizAppsTaskRecordLike[];
|
|
142
|
+
get SelectedTaskParent(): BizAppsTaskRecordLike | null;
|
|
143
|
+
OpenTaskRecord(taskId: string, event?: Event): void;
|
|
144
|
+
CloseTaskDrawer(): void;
|
|
145
|
+
OpenFullTaskForm(): void;
|
|
146
|
+
MarkTaskDirty(): void;
|
|
147
|
+
OnTaskStatusChange(event: Event): void;
|
|
148
|
+
OnTaskHealthChange(event: Event): void;
|
|
149
|
+
OnTaskPercentChange(event: Event): void;
|
|
150
|
+
OnTaskConfidenceChange(event: Event): void;
|
|
151
|
+
OnTaskDueAtChange(event: Event): void;
|
|
152
|
+
OnTaskDescriptionChange(event: Event): void;
|
|
153
|
+
private _updateRecordActionId;
|
|
154
|
+
private resolveUpdateRecordActionId;
|
|
155
|
+
SaveTaskEdits(): Promise<void>;
|
|
156
|
+
private formatDateForInput;
|
|
157
|
+
OpenPolicyEntityRecord(): void;
|
|
158
|
+
OpenRoutineEntityRecord(routineId: string, event?: Event): void;
|
|
159
|
+
OpenRequestDetail(request: MJAIAgentRequestEntity): void;
|
|
160
|
+
OnRequestDialogClose(result: AgentRequestPanelResult): void;
|
|
161
|
+
QuickRespondToRequest(request: MJAIAgentRequestEntity, decision: 'Approved' | 'Rejected', event: Event): Promise<void>;
|
|
162
|
+
TriggerWakeNow(routine: MJUserRoutineEntity, event?: Event): Promise<void>;
|
|
163
|
+
ToggleRoutineStatus(routine: MJUserRoutineEntity, event?: Event): Promise<void>;
|
|
164
|
+
MarkPolicyDirty(): void;
|
|
165
|
+
SetCoordinationMode(mode: PolicyCoordinationModeValue): void;
|
|
166
|
+
SetPolicyStatus(status: PolicyStatusValue): void;
|
|
167
|
+
ToggleApprovalGuardrail(field: 'AllowInterAgentCoordination' | 'RequireApprovalForExternalComms' | 'RequireApprovalForFinancials' | 'RequireApprovalForDestructiveActions'): void;
|
|
168
|
+
OnDisplayNameInput(event: Event): void;
|
|
169
|
+
OnThresholdInputEvent(event: Event): void;
|
|
170
|
+
OnInstructionsOverrideInput(event: Event): void;
|
|
171
|
+
OnThresholdInput(rawValue: string): void;
|
|
172
|
+
ResetDraftPolicy(): void;
|
|
173
|
+
SaveGovernancePolicy(): Promise<void>;
|
|
174
|
+
DismissBanner(): void;
|
|
175
|
+
/**
|
|
176
|
+
* Resolve the filter scoping Tasks to the signed-in user's linked person. Returns null (and clears
|
|
177
|
+
* `HasLinkedPerson`) when no person is linked, or when the lookup fails after surfacing the error.
|
|
178
|
+
*/
|
|
179
|
+
private resolveTaskScopeFilter;
|
|
180
|
+
private buildTasksViewParams;
|
|
181
|
+
/** Badge class for a task's `Priority` (Critical/High/Medium/Low). */
|
|
182
|
+
GetTaskPriorityClass(priority: string | null): string;
|
|
183
|
+
private showBanner;
|
|
184
|
+
GetHealthBadgeLabel(health: TaskHealthStatus): string;
|
|
185
|
+
GetHealthBadgeIcon(health: TaskHealthStatus): string;
|
|
186
|
+
GetPriorityTierLabel(priority: number): string;
|
|
187
|
+
GetPriorityTierClass(priority: number): string;
|
|
188
|
+
IsRequestExpired(request: MJAIAgentRequestEntity): boolean;
|
|
189
|
+
private publishAgentContext;
|
|
190
|
+
private registerAgentTools;
|
|
191
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ChiefOfStaffDashboardComponent, never>;
|
|
192
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ChiefOfStaffDashboardComponent, "mj-chief-of-staff-dashboard", never, {}, {}, never, never, false, never>;
|
|
193
|
+
}
|
|
194
|
+
export declare function LoadChiefOfStaffDashboard(): void;
|
|
195
|
+
//# sourceMappingURL=chief-of-staff-dashboard.component.d.ts.map
|