@miragon/pulse-analytics-connector 0.0.0-bootstrap.0 → 0.21.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/LICENSE +21 -0
- package/README.md +86 -3
- package/dist/bpmn-name-lookup.d.ts +72 -0
- package/dist/bpmn-name-lookup.d.ts.map +1 -0
- package/dist/bpmn-name-lookup.js +123 -0
- package/dist/bpmn-name-lookup.js.map +1 -0
- package/dist/bpmn-name-lookup.test.d.ts +2 -0
- package/dist/bpmn-name-lookup.test.d.ts.map +1 -0
- package/dist/bpmn-name-lookup.test.js +287 -0
- package/dist/bpmn-name-lookup.test.js.map +1 -0
- package/dist/bpmn-names.d.ts +38 -0
- package/dist/bpmn-names.d.ts.map +1 -0
- package/dist/bpmn-names.js +22 -0
- package/dist/bpmn-names.js.map +1 -0
- package/dist/brand-gates.test.d.ts +2 -0
- package/dist/brand-gates.test.d.ts.map +1 -0
- package/dist/brand-gates.test.js +58 -0
- package/dist/brand-gates.test.js.map +1 -0
- package/dist/builder-texts.d.ts +4 -0
- package/dist/builder-texts.d.ts.map +1 -0
- package/dist/builder-texts.js +14 -0
- package/dist/builder-texts.js.map +1 -0
- package/dist/builder-texts.test.d.ts +2 -0
- package/dist/builder-texts.test.d.ts.map +1 -0
- package/dist/builder-texts.test.js +32 -0
- package/dist/builder-texts.test.js.map +1 -0
- package/dist/definition.d.ts +3 -0
- package/dist/definition.d.ts.map +1 -0
- package/dist/definition.js +151 -0
- package/dist/definition.js.map +1 -0
- package/dist/engine-ids.d.ts +42 -0
- package/dist/engine-ids.d.ts.map +1 -0
- package/dist/engine-ids.js +50 -0
- package/dist/engine-ids.js.map +1 -0
- package/dist/engine-scope.test.d.ts +2 -0
- package/dist/engine-scope.test.d.ts.map +1 -0
- package/dist/engine-scope.test.js +260 -0
- package/dist/engine-scope.test.js.map +1 -0
- package/dist/heatmap-data.d.ts +15 -0
- package/dist/heatmap-data.d.ts.map +1 -0
- package/dist/heatmap-data.js +2 -0
- package/dist/heatmap-data.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/instructions.d.ts +8 -0
- package/dist/instructions.d.ts.map +1 -0
- package/dist/instructions.js +33 -0
- package/dist/instructions.js.map +1 -0
- package/dist/messages/de.ask-ai.d.ts +9 -0
- package/dist/messages/de.ask-ai.d.ts.map +1 -0
- package/dist/messages/de.ask-ai.js +18 -0
- package/dist/messages/de.ask-ai.js.map +1 -0
- package/dist/messages/de.builder.d.ts +12 -0
- package/dist/messages/de.builder.d.ts.map +1 -0
- package/dist/messages/de.builder.js +53 -0
- package/dist/messages/de.builder.js.map +1 -0
- package/dist/messages/de.server.d.ts +8 -0
- package/dist/messages/de.server.d.ts.map +1 -0
- package/dist/messages/de.server.js +26 -0
- package/dist/messages/de.server.js.map +1 -0
- package/dist/messages/de.sweep.d.ts +10 -0
- package/dist/messages/de.sweep.d.ts.map +1 -0
- package/dist/messages/de.sweep.js +203 -0
- package/dist/messages/de.sweep.js.map +1 -0
- package/dist/messages/en.ask-ai.d.ts +25 -0
- package/dist/messages/en.ask-ai.d.ts.map +1 -0
- package/dist/messages/en.ask-ai.js +24 -0
- package/dist/messages/en.ask-ai.js.map +1 -0
- package/dist/messages/en.builder.d.ts +12 -0
- package/dist/messages/en.builder.d.ts.map +1 -0
- package/dist/messages/en.builder.js +53 -0
- package/dist/messages/en.builder.js.map +1 -0
- package/dist/messages/en.server.d.ts +8 -0
- package/dist/messages/en.server.d.ts.map +1 -0
- package/dist/messages/en.server.js +26 -0
- package/dist/messages/en.server.js.map +1 -0
- package/dist/messages/en.sweep.d.ts +11 -0
- package/dist/messages/en.sweep.d.ts.map +1 -0
- package/dist/messages/en.sweep.js +204 -0
- package/dist/messages/en.sweep.js.map +1 -0
- package/dist/messages/glossary.d.ts +26 -0
- package/dist/messages/glossary.d.ts.map +1 -0
- package/dist/messages/glossary.js +37 -0
- package/dist/messages/glossary.js.map +1 -0
- package/dist/messages/glossary.test.d.ts +2 -0
- package/dist/messages/glossary.test.d.ts.map +1 -0
- package/dist/messages/glossary.test.js +109 -0
- package/dist/messages/glossary.test.js.map +1 -0
- package/dist/messages/index.d.ts +12 -0
- package/dist/messages/index.d.ts.map +1 -0
- package/dist/messages/index.js +23 -0
- package/dist/messages/index.js.map +1 -0
- package/dist/messages/plural.d.ts +10 -0
- package/dist/messages/plural.d.ts.map +1 -0
- package/dist/messages/plural.js +17 -0
- package/dist/messages/plural.js.map +1 -0
- package/dist/messages/use-t.d.ts +10 -0
- package/dist/messages/use-t.d.ts.map +1 -0
- package/dist/messages/use-t.js +10 -0
- package/dist/messages/use-t.js.map +1 -0
- package/dist/module.d.ts +48 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +174 -0
- package/dist/module.js.map +1 -0
- package/dist/module.test.d.ts +2 -0
- package/dist/module.test.d.ts.map +1 -0
- package/dist/module.test.js +230 -0
- package/dist/module.test.js.map +1 -0
- package/dist/named-views.d.ts +27 -0
- package/dist/named-views.d.ts.map +1 -0
- package/dist/named-views.js +73 -0
- package/dist/named-views.js.map +1 -0
- package/dist/named-views.test.d.ts +2 -0
- package/dist/named-views.test.d.ts.map +1 -0
- package/dist/named-views.test.js +110 -0
- package/dist/named-views.test.js.map +1 -0
- package/dist/plugin.d.ts +44 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +52 -0
- package/dist/plugin.js.map +1 -0
- package/dist/prometheus-wiring.test.d.ts +2 -0
- package/dist/prometheus-wiring.test.d.ts.map +1 -0
- package/dist/prometheus-wiring.test.js +142 -0
- package/dist/prometheus-wiring.test.js.map +1 -0
- package/dist/server-locale.d.ts +48 -0
- package/dist/server-locale.d.ts.map +1 -0
- package/dist/server-locale.js +33 -0
- package/dist/server-locale.js.map +1 -0
- package/dist/settings-tools.d.ts +23 -0
- package/dist/settings-tools.d.ts.map +1 -0
- package/dist/settings-tools.js +100 -0
- package/dist/settings-tools.js.map +1 -0
- package/dist/settings.d.ts +77 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +99 -0
- package/dist/settings.js.map +1 -0
- package/dist/settings.test.d.ts +2 -0
- package/dist/settings.test.d.ts.map +1 -0
- package/dist/settings.test.js +299 -0
- package/dist/settings.test.js.map +1 -0
- package/dist/steps/app-config.d.ts +30 -0
- package/dist/steps/app-config.d.ts.map +1 -0
- package/dist/steps/app-config.js +46 -0
- package/dist/steps/app-config.js.map +1 -0
- package/dist/steps/dashboard.d.ts +12 -0
- package/dist/steps/dashboard.d.ts.map +1 -0
- package/dist/steps/dashboard.js +58 -0
- package/dist/steps/dashboard.js.map +1 -0
- package/dist/steps/failure-dashboard.d.ts +10 -0
- package/dist/steps/failure-dashboard.d.ts.map +1 -0
- package/dist/steps/failure-dashboard.js +32 -0
- package/dist/steps/failure-dashboard.js.map +1 -0
- package/dist/steps/index.d.ts +3 -0
- package/dist/steps/index.d.ts.map +1 -0
- package/dist/steps/index.js +3 -0
- package/dist/steps/index.js.map +1 -0
- package/dist/steps/steps.test.d.ts +2 -0
- package/dist/steps/steps.test.d.ts.map +1 -0
- package/dist/steps/steps.test.js +153 -0
- package/dist/steps/steps.test.js.map +1 -0
- package/dist/tool-names.d.ts +13 -0
- package/dist/tool-names.d.ts.map +1 -0
- package/dist/tool-names.js +27 -0
- package/dist/tool-names.js.map +1 -0
- package/dist/tools/cluster-compare.d.ts +8 -0
- package/dist/tools/cluster-compare.d.ts.map +1 -0
- package/dist/tools/cluster-compare.js +17 -0
- package/dist/tools/cluster-compare.js.map +1 -0
- package/dist/tools/element.d.ts +8 -0
- package/dist/tools/element.d.ts.map +1 -0
- package/dist/tools/element.js +25 -0
- package/dist/tools/element.js.map +1 -0
- package/dist/tools/engine-compare.d.ts +8 -0
- package/dist/tools/engine-compare.d.ts.map +1 -0
- package/dist/tools/engine-compare.js +18 -0
- package/dist/tools/engine-compare.js.map +1 -0
- package/dist/tools/engine-compare.test.d.ts +2 -0
- package/dist/tools/engine-compare.test.d.ts.map +1 -0
- package/dist/tools/engine-compare.test.js +166 -0
- package/dist/tools/engine-compare.test.js.map +1 -0
- package/dist/tools/engine-landscape.d.ts +7 -0
- package/dist/tools/engine-landscape.d.ts.map +1 -0
- package/dist/tools/engine-landscape.js +13 -0
- package/dist/tools/engine-landscape.js.map +1 -0
- package/dist/tools/engine-landscape.test.d.ts +2 -0
- package/dist/tools/engine-landscape.test.d.ts.map +1 -0
- package/dist/tools/engine-landscape.test.js +110 -0
- package/dist/tools/engine-landscape.test.js.map +1 -0
- package/dist/tools/failures.d.ts +7 -0
- package/dist/tools/failures.d.ts.map +1 -0
- package/dist/tools/failures.js +13 -0
- package/dist/tools/failures.js.map +1 -0
- package/dist/tools/health.d.ts +7 -0
- package/dist/tools/health.d.ts.map +1 -0
- package/dist/tools/health.js +23 -0
- package/dist/tools/health.js.map +1 -0
- package/dist/tools/health.test.d.ts +2 -0
- package/dist/tools/health.test.d.ts.map +1 -0
- package/dist/tools/health.test.js +119 -0
- package/dist/tools/health.test.js.map +1 -0
- package/dist/tools/index.d.ts +18 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +35 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/performance.d.ts +8 -0
- package/dist/tools/performance.d.ts.map +1 -0
- package/dist/tools/performance.js +25 -0
- package/dist/tools/performance.js.map +1 -0
- package/dist/tools/performance.test.d.ts +2 -0
- package/dist/tools/performance.test.d.ts.map +1 -0
- package/dist/tools/performance.test.js +176 -0
- package/dist/tools/performance.test.js.map +1 -0
- package/dist/tools/version-compare.d.ts +8 -0
- package/dist/tools/version-compare.d.ts.map +1 -0
- package/dist/tools/version-compare.js +17 -0
- package/dist/tools/version-compare.js.map +1 -0
- package/dist/tools/version-compare.test.d.ts +2 -0
- package/dist/tools/version-compare.test.d.ts.map +1 -0
- package/dist/tools/version-compare.test.js +82 -0
- package/dist/tools/version-compare.test.js.map +1 -0
- package/dist/toolsets.d.ts +17 -0
- package/dist/toolsets.d.ts.map +1 -0
- package/dist/toolsets.js +47 -0
- package/dist/toolsets.js.map +1 -0
- package/dist/toolsets.test.d.ts +2 -0
- package/dist/toolsets.test.d.ts.map +1 -0
- package/dist/toolsets.test.js +91 -0
- package/dist/toolsets.test.js.map +1 -0
- package/dist/view-title.test.d.ts +2 -0
- package/dist/view-title.test.d.ts.map +1 -0
- package/dist/view-title.test.js +91 -0
- package/dist/view-title.test.js.map +1 -0
- package/dist/widget-tools/comparisons.d.ts +13 -0
- package/dist/widget-tools/comparisons.d.ts.map +1 -0
- package/dist/widget-tools/comparisons.js +177 -0
- package/dist/widget-tools/comparisons.js.map +1 -0
- package/dist/widget-tools/comparisons.test.d.ts +2 -0
- package/dist/widget-tools/comparisons.test.d.ts.map +1 -0
- package/dist/widget-tools/comparisons.test.js +123 -0
- package/dist/widget-tools/comparisons.test.js.map +1 -0
- package/dist/widget-tools/shared.d.ts +36 -0
- package/dist/widget-tools/shared.d.ts.map +1 -0
- package/dist/widget-tools/shared.js +39 -0
- package/dist/widget-tools/shared.js.map +1 -0
- package/dist/widget-tools.d.ts +25 -0
- package/dist/widget-tools.d.ts.map +1 -0
- package/dist/widget-tools.js +269 -0
- package/dist/widget-tools.js.map +1 -0
- package/dist/widget-tools.test.d.ts +2 -0
- package/dist/widget-tools.test.d.ts.map +1 -0
- package/dist/widget-tools.test.js +272 -0
- package/dist/widget-tools.test.js.map +1 -0
- package/package.json +91 -5
- package/src/bpmn-name-lookup.test.ts +333 -0
- package/src/bpmn-name-lookup.ts +197 -0
- package/src/bpmn-names.ts +51 -0
- package/src/brand-gates.test.ts +69 -0
- package/src/builder-texts.test.ts +40 -0
- package/src/builder-texts.ts +15 -0
- package/src/definition.ts +181 -0
- package/src/engine-ids.ts +85 -0
- package/src/engine-scope.test.ts +324 -0
- package/src/heatmap-data.ts +14 -0
- package/src/index.ts +4 -0
- package/src/instructions.ts +33 -0
- package/src/messages/GLOSSARY.md +88 -0
- package/src/messages/de.ask-ai.ts +28 -0
- package/src/messages/de.builder.ts +77 -0
- package/src/messages/de.server.ts +39 -0
- package/src/messages/de.sweep.ts +244 -0
- package/src/messages/en.ask-ai.ts +34 -0
- package/src/messages/en.builder.ts +76 -0
- package/src/messages/en.server.ts +39 -0
- package/src/messages/en.sweep.ts +240 -0
- package/src/messages/glossary.test.ts +122 -0
- package/src/messages/glossary.ts +62 -0
- package/src/messages/index.ts +24 -0
- package/src/messages/plural.ts +18 -0
- package/src/messages/use-t.ts +12 -0
- package/src/module.test.ts +319 -0
- package/src/module.ts +211 -0
- package/src/named-views.test.ts +141 -0
- package/src/named-views.ts +97 -0
- package/src/plugin.ts +94 -0
- package/src/prometheus-wiring.test.ts +174 -0
- package/src/server-locale.ts +59 -0
- package/src/settings-tools.ts +170 -0
- package/src/settings.test.ts +402 -0
- package/src/settings.ts +114 -0
- package/src/steps/app-config.ts +75 -0
- package/src/steps/dashboard.ts +73 -0
- package/src/steps/failure-dashboard.ts +38 -0
- package/src/steps/index.ts +2 -0
- package/src/steps/steps.test.ts +216 -0
- package/src/tool-names.ts +26 -0
- package/src/tools/cluster-compare.ts +28 -0
- package/src/tools/element.ts +35 -0
- package/src/tools/engine-compare.test.ts +210 -0
- package/src/tools/engine-compare.ts +30 -0
- package/src/tools/engine-landscape.test.ts +138 -0
- package/src/tools/engine-landscape.ts +21 -0
- package/src/tools/failures.ts +19 -0
- package/src/tools/health.test.ts +156 -0
- package/src/tools/health.ts +29 -0
- package/src/tools/index.ts +44 -0
- package/src/tools/performance.test.ts +210 -0
- package/src/tools/performance.ts +38 -0
- package/src/tools/version-compare.test.ts +97 -0
- package/src/tools/version-compare.ts +28 -0
- package/src/toolsets.test.ts +107 -0
- package/src/toolsets.ts +56 -0
- package/src/view-title.test.ts +123 -0
- package/src/widget-tools/comparisons.test.ts +170 -0
- package/src/widget-tools/comparisons.ts +229 -0
- package/src/widget-tools/shared.ts +67 -0
- package/src/widget-tools.test.ts +306 -0
- package/src/widget-tools.ts +375 -0
- package/src/widgets/analytics-dashboard/activity-bottleneck-table.tsx +179 -0
- package/src/widgets/analytics-dashboard/definition-breakdown.tsx +108 -0
- package/src/widgets/analytics-dashboard/execution-performance-kpi.tsx +94 -0
- package/src/widgets/analytics-dashboard/execution-summary-kpi.tsx +122 -0
- package/src/widgets/analytics-dashboard/lib.ts +43 -0
- package/src/widgets/bpmn-heatmap.test.tsx +75 -0
- package/src/widgets/bpmn-heatmap.tsx +127 -0
- package/src/widgets/catalogue-sync.test.ts +16 -0
- package/src/widgets/cluster-compare.tsx +148 -0
- package/src/widgets/comparison-shared.test.ts +237 -0
- package/src/widgets/comparison-shared.tsx +371 -0
- package/src/widgets/comparison-widgets.test.tsx +307 -0
- package/src/widgets/dashboard-widgets.test.tsx +397 -0
- package/src/widgets/engine-compare.tsx +87 -0
- package/src/widgets/engine-landscape.tsx +352 -0
- package/src/widgets/failure-dashboard/error-patterns-table.tsx +122 -0
- package/src/widgets/failure-dashboard/failure-rate-table.test.ts +80 -0
- package/src/widgets/failure-dashboard/failure-rate-table.tsx +170 -0
- package/src/widgets/failure-dashboard/lib.ts +32 -0
- package/src/widgets/failure-dashboard/summary-kpi.tsx +122 -0
- package/src/widgets/failure-landscape-widgets.test.tsx +393 -0
- package/src/widgets/figure.tsx +79 -0
- package/src/widgets/hand-off.test.ts +126 -0
- package/src/widgets/hand-off.ts +102 -0
- package/src/widgets/index.ts +124 -0
- package/src/widgets/model-descriptions.dashboard.test.ts +280 -0
- package/src/widgets/model-descriptions.test.ts +251 -0
- package/src/widgets/model-descriptions.ts +428 -0
- package/src/widgets/names.test.ts +32 -0
- package/src/widgets/names.ts +39 -0
- package/src/widgets/query-gate.test.tsx +57 -0
- package/src/widgets/query-gate.tsx +50 -0
- package/src/widgets/settings-section.test.tsx +174 -0
- package/src/widgets/settings-section.tsx +244 -0
- package/src/widgets/version-compare.test.ts +68 -0
- package/src/widgets/version-compare.tsx +96 -0
- package/src/widgets/view-meta.ts +18 -0
- package/src/widgets/widget-render.test-support.tsx +103 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { TONE_DOT, cn } from "@miragon/mcp-toolkit-ui"
|
|
2
|
+
import {
|
|
3
|
+
HandOffButton,
|
|
4
|
+
ListTable,
|
|
5
|
+
NamedId,
|
|
6
|
+
Section,
|
|
7
|
+
TableEmptyState,
|
|
8
|
+
TableSkeleton,
|
|
9
|
+
Td,
|
|
10
|
+
WidgetShell,
|
|
11
|
+
formatNumber,
|
|
12
|
+
type ListTableColumn,
|
|
13
|
+
} from "@miragon/pulse-widget-shell/widgets"
|
|
14
|
+
import type { FailureDashboardData, ProcessFailureItem } from "@miragon/pulse-analytics-client"
|
|
15
|
+
import { useFailureDashboardSelfFetch, type FailureScopeProps, type FailureView } from "./lib.js"
|
|
16
|
+
import { QueryGate } from "../query-gate.js"
|
|
17
|
+
import { useT, type T } from "../../messages/use-t.js"
|
|
18
|
+
import { engineIdsOf, useHandOff, type HandOff } from "../hand-off.js"
|
|
19
|
+
import { processNameOf } from "../../bpmn-names.js"
|
|
20
|
+
import { Figure, FigureLegend, StateCount } from "../figure.js"
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* What drives ONE process's open incidents right now (live gauges: open
|
|
24
|
+
* incidents per 100 running instances, dead jobs — #336). The regression
|
|
25
|
+
* check goes to the tools that measure incident rates over time —
|
|
26
|
+
* analytics_version_compare cannot split incidents by version, so its
|
|
27
|
+
* incident rates are null (#327).
|
|
28
|
+
*/
|
|
29
|
+
export function failureRateHandOff(
|
|
30
|
+
proc: ProcessFailureItem,
|
|
31
|
+
data: Pick<FailureDashboardData, "engines">,
|
|
32
|
+
): HandOff {
|
|
33
|
+
return {
|
|
34
|
+
intent: "askAi.failureRate",
|
|
35
|
+
ids: { engine: engineIdsOf(data.engines), processDefinitionKey: proc.processDefinitionKey },
|
|
36
|
+
// A rate over no running instance is null — left out, never a 0.
|
|
37
|
+
facts: {
|
|
38
|
+
openIncidentsNow: proc.openIncidents,
|
|
39
|
+
runningNow: proc.runningNow,
|
|
40
|
+
incidentRatePct: proc.incidentRatePct,
|
|
41
|
+
deadJobs: proc.deadJobs,
|
|
42
|
+
},
|
|
43
|
+
tools: [
|
|
44
|
+
"analytics_compare_execution_periods",
|
|
45
|
+
"analytics_cluster_compare",
|
|
46
|
+
"analytics_element_bottleneck",
|
|
47
|
+
],
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The bar's length: the rate against the largest rate in the table, so
|
|
53
|
+
* every bar is comparable and none is cut off. A rate of incidents per 100
|
|
54
|
+
* running instances may pass 100 (one instance can carry several), which a
|
|
55
|
+
* scale capped at 100 would hide.
|
|
56
|
+
*/
|
|
57
|
+
export function rateBarWidth(rate: number, max: number): number {
|
|
58
|
+
if (!(max > 0) || !(rate > 0)) return 0
|
|
59
|
+
return Math.min(100, (rate / max) * 100)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function columns(t: T): ListTableColumn[] {
|
|
63
|
+
return [
|
|
64
|
+
{ label: t("aFailureRate.colProcess") },
|
|
65
|
+
{ label: t("aFailureRate.colRunningNow"), align: "right" },
|
|
66
|
+
{ label: t("aFailureRate.colOpenIncidents"), align: "right" },
|
|
67
|
+
{ label: t("aFailureRate.colDeadJobs"), align: "right" },
|
|
68
|
+
{ label: t("aFailureRate.colIncidentRate"), align: "right" },
|
|
69
|
+
{
|
|
70
|
+
label: <span className="sr-only">{t("aFailureRate.colAi")}</span>,
|
|
71
|
+
plain: true,
|
|
72
|
+
sticky: true,
|
|
73
|
+
},
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The rate as a number over a bar. The bar is a magnitude, not a state: it
|
|
79
|
+
* takes the data-viz blue (decision j), not the danger red. A rate is judged
|
|
80
|
+
* only against a threshold or the period before (U17), and this live ratio
|
|
81
|
+
* has neither; the open incidents beside it already carry the danger.
|
|
82
|
+
*/
|
|
83
|
+
function RateCell({ rate, max, t }: { rate: number | null; max: number; t: T }) {
|
|
84
|
+
if (rate === null) return <Figure value={null} why={t("aFigure.noRate")} />
|
|
85
|
+
return (
|
|
86
|
+
<span className="ml-auto flex w-24 flex-col items-end gap-1">
|
|
87
|
+
<span className="tabular-nums">{formatNumber(rate, { maximumFractionDigits: 1 })}</span>
|
|
88
|
+
<span aria-hidden="true" className="bg-muted block h-1.5 w-full overflow-hidden rounded-full">
|
|
89
|
+
<span
|
|
90
|
+
className={cn("block h-full rounded-full", TONE_DOT.info)}
|
|
91
|
+
style={{ width: `${rateBarWidth(rate, max)}%` }}
|
|
92
|
+
/>
|
|
93
|
+
</span>
|
|
94
|
+
</span>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function FailureRateTable({
|
|
99
|
+
data: initialData,
|
|
100
|
+
engine,
|
|
101
|
+
}: { data: FailureView | null } & FailureScopeProps) {
|
|
102
|
+
const fallbackQuery = useFailureDashboardSelfFetch(initialData, { engine })
|
|
103
|
+
const t = useT()
|
|
104
|
+
const { ask } = useHandOff()
|
|
105
|
+
return (
|
|
106
|
+
<QueryGate initialData={initialData} query={fallbackQuery} skeleton={<TableSkeleton />}>
|
|
107
|
+
{(data) => {
|
|
108
|
+
if (data.processBreakdown.length === 0) {
|
|
109
|
+
return (
|
|
110
|
+
<WidgetShell>
|
|
111
|
+
<TableEmptyState variant="done">{t("aFailureRate.emptyState")}</TableEmptyState>
|
|
112
|
+
</WidgetShell>
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
const max = Math.max(0, ...data.processBreakdown.map((p) => p.incidentRatePct ?? 0))
|
|
116
|
+
return (
|
|
117
|
+
<WidgetShell>
|
|
118
|
+
<Section
|
|
119
|
+
title={t("aFailureRate.heading")}
|
|
120
|
+
count={data.processBreakdown.length}
|
|
121
|
+
defaultOpen
|
|
122
|
+
>
|
|
123
|
+
<ListTable ariaLabel={t("aFailureRate.tableLabel")} columns={columns(t)}>
|
|
124
|
+
{data.processBreakdown.map((proc) => (
|
|
125
|
+
<tr key={proc.processDefinitionKey}>
|
|
126
|
+
<Td>
|
|
127
|
+
<NamedId
|
|
128
|
+
name={processNameOf(data.names, proc.processDefinitionKey)}
|
|
129
|
+
id={proc.processDefinitionKey}
|
|
130
|
+
/>
|
|
131
|
+
</Td>
|
|
132
|
+
<Td align="right" className="tabular-nums">
|
|
133
|
+
{formatNumber(proc.runningNow)}
|
|
134
|
+
</Td>
|
|
135
|
+
{/* The states of a process (decision f), on the kit's one
|
|
136
|
+
ladder: open incidents and dead jobs (no retries left)
|
|
137
|
+
edged in danger while there are any, as camunda7 and
|
|
138
|
+
the landscape show them; none is a plain count. */}
|
|
139
|
+
<Td align="right" className="tabular-nums">
|
|
140
|
+
<StateCount value={proc.openIncidents} />
|
|
141
|
+
</Td>
|
|
142
|
+
<Td align="right" className="tabular-nums">
|
|
143
|
+
<StateCount value={proc.deadJobs} />
|
|
144
|
+
</Td>
|
|
145
|
+
<Td align="right">
|
|
146
|
+
<RateCell rate={proc.incidentRatePct} max={max} t={t} />
|
|
147
|
+
</Td>
|
|
148
|
+
<Td align="right">
|
|
149
|
+
<HandOffButton
|
|
150
|
+
action="findCause"
|
|
151
|
+
variant="icon"
|
|
152
|
+
prompt={ask(failureRateHandOff(proc, data))}
|
|
153
|
+
/>
|
|
154
|
+
</Td>
|
|
155
|
+
</tr>
|
|
156
|
+
))}
|
|
157
|
+
</ListTable>
|
|
158
|
+
<FigureLegend
|
|
159
|
+
reasons={[
|
|
160
|
+
data.processBreakdown.some((p) => p.incidentRatePct === null) &&
|
|
161
|
+
t("aFigure.noRate"),
|
|
162
|
+
]}
|
|
163
|
+
/>
|
|
164
|
+
</Section>
|
|
165
|
+
</WidgetShell>
|
|
166
|
+
)
|
|
167
|
+
}}
|
|
168
|
+
</QueryGate>
|
|
169
|
+
)
|
|
170
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useToolQuery } from "@miragon/mcp-toolkit-ui"
|
|
2
|
+
import type { EngineFilterInput, FailureDashboardData } from "@miragon/pulse-analytics-client"
|
|
3
|
+
import type { Named } from "../../bpmn-names.js"
|
|
4
|
+
import { ANALYTICS_FAILURE_DASHBOARD_DATA } from "../../tool-names.js"
|
|
5
|
+
|
|
6
|
+
/** The failure payload the widgets read: the figures plus the process names behind their keys. */
|
|
7
|
+
export type FailureView = Named<FailureDashboardData>
|
|
8
|
+
|
|
9
|
+
/** The cell props every failure widget takes — the engine scope its self-fetch reads. */
|
|
10
|
+
export interface FailureScopeProps {
|
|
11
|
+
/** Configured engine id(s); omitted = every configured engine (the feed resolves it). */
|
|
12
|
+
engine?: EngineFilterInput
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Centralised so the three failure widgets share one self-fetch contract. The
|
|
16
|
+
// failure dashboard is point-in-time (live state gauges), so there is no period
|
|
17
|
+
// scope — only the engine scope, carried in the args AND the cache key so an
|
|
18
|
+
// engine-scoped cell never reads a fleet-wide entry. Self-fetches the app-only
|
|
19
|
+
// *_data feed — calling the show_* tool from inside the iframe is host-defined
|
|
20
|
+
// behavior (hosts honoring resultCanProduceWidget may render a second widget
|
|
21
|
+
// per refresh).
|
|
22
|
+
export function useFailureDashboardSelfFetch(
|
|
23
|
+
initialData: FailureView | null,
|
|
24
|
+
{ engine }: FailureScopeProps,
|
|
25
|
+
) {
|
|
26
|
+
return useToolQuery<FailureView>(
|
|
27
|
+
["analytics:failure-dashboard", engine ?? null],
|
|
28
|
+
ANALYTICS_FAILURE_DASHBOARD_DATA,
|
|
29
|
+
engine === undefined ? {} : { engine },
|
|
30
|
+
{ enabled: !initialData },
|
|
31
|
+
)
|
|
32
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HandOffButton,
|
|
3
|
+
ViewMeta,
|
|
4
|
+
WidgetShell,
|
|
5
|
+
formatNumber,
|
|
6
|
+
} from "@miragon/pulse-widget-shell/widgets"
|
|
7
|
+
import type { FailureDashboardData } from "@miragon/pulse-analytics-client"
|
|
8
|
+
import { KpiGrid, KpiGridSkeleton, WidgetHeader, cn, type KpiCell } from "@miragon/mcp-toolkit-ui"
|
|
9
|
+
import { useFailureDashboardSelfFetch, type FailureScopeProps, type FailureView } from "./lib.js"
|
|
10
|
+
import { QueryGate } from "../query-gate.js"
|
|
11
|
+
import { useT, type T } from "../../messages/use-t.js"
|
|
12
|
+
import { processNameOf } from "../../bpmn-names.js"
|
|
13
|
+
import { engineIdsOf, useHandOff, type HandOff } from "../hand-off.js"
|
|
14
|
+
import { enginesMeta } from "../view-meta.js"
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Triage of the open-incident snapshot. Only the headline numbers travel —
|
|
18
|
+
* the patterns themselves are read through the tools (bounded, and their
|
|
19
|
+
* messages stay tool output instead of the user's own words).
|
|
20
|
+
*/
|
|
21
|
+
export function failureSummaryHandOff(data: FailureDashboardData): HandOff {
|
|
22
|
+
return {
|
|
23
|
+
intent: "askAi.failureSummary",
|
|
24
|
+
ids: { engine: engineIdsOf(data.engines) },
|
|
25
|
+
facts: {
|
|
26
|
+
openIncidentsNow: data.totalIncidents,
|
|
27
|
+
incidentGroups: data.uniqueErrorPatterns,
|
|
28
|
+
mostAffectedProcess: data.mostAffectedProcess,
|
|
29
|
+
},
|
|
30
|
+
tools: [
|
|
31
|
+
"analytics_find_failed_instances",
|
|
32
|
+
"analytics_show_failure_dashboard",
|
|
33
|
+
"camunda7_list_incidents",
|
|
34
|
+
"camunda7_query_historic_incidents",
|
|
35
|
+
],
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The most affected process as a figure: its name (the key below it, quiet),
|
|
41
|
+
* or the key alone in mono when the model's name is unknown. With no open
|
|
42
|
+
* incident no process is affected, and the cell says so in quiet words: "—"
|
|
43
|
+
* means a figure nobody measured (U17), and this one is known.
|
|
44
|
+
*/
|
|
45
|
+
function mostAffectedCell(t: T, data: FailureView): KpiCell {
|
|
46
|
+
const label = t("aFailureSummary.mostAffected")
|
|
47
|
+
const key = data.mostAffectedProcess
|
|
48
|
+
if (!key) {
|
|
49
|
+
return {
|
|
50
|
+
label,
|
|
51
|
+
value: (
|
|
52
|
+
<span className="text-section text-muted-foreground block">
|
|
53
|
+
{t("aFailureSummary.mostAffectedNone")}
|
|
54
|
+
</span>
|
|
55
|
+
),
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const name = processNameOf(data.names, key)
|
|
59
|
+
return {
|
|
60
|
+
label,
|
|
61
|
+
value: (
|
|
62
|
+
<span className={cn("text-section block break-words", !name && "font-mono")}>
|
|
63
|
+
{name ?? key}
|
|
64
|
+
</span>
|
|
65
|
+
),
|
|
66
|
+
trend: name ? <span className="font-mono break-all">{key}</span> : undefined,
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function FailureSummaryKpi({
|
|
71
|
+
data: initialData,
|
|
72
|
+
engine,
|
|
73
|
+
}: { data: FailureView | null } & FailureScopeProps) {
|
|
74
|
+
const fallbackQuery = useFailureDashboardSelfFetch(initialData, { engine })
|
|
75
|
+
const t = useT()
|
|
76
|
+
const { ask } = useHandOff()
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<QueryGate
|
|
80
|
+
initialData={initialData}
|
|
81
|
+
query={fallbackQuery}
|
|
82
|
+
header={<WidgetHeader title={t("aFailureSummary.title")} />}
|
|
83
|
+
skeleton={<KpiGridSkeleton cells={3} boxed />}
|
|
84
|
+
>
|
|
85
|
+
{(data) => (
|
|
86
|
+
<WidgetShell>
|
|
87
|
+
<WidgetHeader
|
|
88
|
+
title={t("aFailureSummary.title")}
|
|
89
|
+
// A live snapshot: no period, the engines and when it was read.
|
|
90
|
+
sub={<ViewMeta engines={enginesMeta(data.engines)} asOf={data.asOf} />}
|
|
91
|
+
actions={
|
|
92
|
+
<HandOffButton
|
|
93
|
+
action="prioritize"
|
|
94
|
+
variant="primary"
|
|
95
|
+
prompt={ask(failureSummaryHandOff(data))}
|
|
96
|
+
/>
|
|
97
|
+
}
|
|
98
|
+
/>
|
|
99
|
+
{/* The dashboards' one KPI pattern (U14): a neutral strip, the state
|
|
100
|
+
as a dot. Only an open incident is a state (danger); how many
|
|
101
|
+
groups they form and which process has the most are neutral. */}
|
|
102
|
+
<KpiGrid
|
|
103
|
+
boxed
|
|
104
|
+
ariaLabel={t("aFailureSummary.summaryAriaLabel")}
|
|
105
|
+
cells={[
|
|
106
|
+
{
|
|
107
|
+
label: t("aFailureSummary.totalIncidents"),
|
|
108
|
+
value: formatNumber(data.totalIncidents),
|
|
109
|
+
tone: data.totalIncidents > 0 ? "danger" : undefined,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
label: t("aFailureSummary.uniqueErrorPatterns"),
|
|
113
|
+
value: formatNumber(data.uniqueErrorPatterns),
|
|
114
|
+
},
|
|
115
|
+
mostAffectedCell(t, data),
|
|
116
|
+
]}
|
|
117
|
+
/>
|
|
118
|
+
</WidgetShell>
|
|
119
|
+
)}
|
|
120
|
+
</QueryGate>
|
|
121
|
+
)
|
|
122
|
+
}
|