@checkstack/healthcheck-frontend 0.0.2
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/CHANGELOG.md +135 -0
- package/package.json +36 -0
- package/src/api.ts +17 -0
- package/src/auto-charts/AutoChartGrid.tsx +383 -0
- package/src/auto-charts/extension.tsx +27 -0
- package/src/auto-charts/index.ts +12 -0
- package/src/auto-charts/schema-parser.ts +121 -0
- package/src/auto-charts/useStrategySchemas.ts +62 -0
- package/src/components/AggregatedDataBanner.tsx +24 -0
- package/src/components/HealthCheckDiagram.tsx +88 -0
- package/src/components/HealthCheckEditor.tsx +136 -0
- package/src/components/HealthCheckHistory.tsx +79 -0
- package/src/components/HealthCheckLatencyChart.tsx +168 -0
- package/src/components/HealthCheckList.tsx +84 -0
- package/src/components/HealthCheckMenuItems.tsx +33 -0
- package/src/components/HealthCheckRunsTable.tsx +187 -0
- package/src/components/HealthCheckSparkline.tsx +46 -0
- package/src/components/HealthCheckStatusTimeline.tsx +190 -0
- package/src/components/HealthCheckSystemOverview.tsx +380 -0
- package/src/components/SystemHealthBadge.tsx +46 -0
- package/src/components/SystemHealthCheckAssignment.tsx +869 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useHealthCheckData.ts +257 -0
- package/src/index.tsx +99 -0
- package/src/pages/HealthCheckConfigPage.tsx +164 -0
- package/src/pages/HealthCheckHistoryDetailPage.tsx +100 -0
- package/src/pages/HealthCheckHistoryPage.tsx +67 -0
- package/src/slots.tsx +185 -0
- package/tsconfig.json +6 -0
package/src/slots.tsx
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSlot,
|
|
3
|
+
createSlotExtension,
|
|
4
|
+
} from "@checkstack/frontend-api";
|
|
5
|
+
import type { PluginMetadata } from "@checkstack/common";
|
|
6
|
+
import type {
|
|
7
|
+
HealthCheckRun,
|
|
8
|
+
AggregatedBucket,
|
|
9
|
+
} from "@checkstack/healthcheck-common";
|
|
10
|
+
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// TYPE DEFINITIONS
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Extends HealthCheckRun with typed result instead of Record<string, unknown>.
|
|
17
|
+
*/
|
|
18
|
+
export type TypedHealthCheckRun<TResult> = Omit<HealthCheckRun, "result"> & {
|
|
19
|
+
result: TResult;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Extends AggregatedBucket with typed aggregatedResult.
|
|
24
|
+
*/
|
|
25
|
+
export type TypedAggregatedBucket<TAggregatedResult> = Omit<
|
|
26
|
+
AggregatedBucket,
|
|
27
|
+
"aggregatedResult"
|
|
28
|
+
> & {
|
|
29
|
+
aggregatedResult?: TAggregatedResult;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Context for raw per-run data visualization.
|
|
34
|
+
*/
|
|
35
|
+
export interface RawDiagramContext<TResult = unknown> {
|
|
36
|
+
type: "raw";
|
|
37
|
+
systemId: string;
|
|
38
|
+
configurationId: string;
|
|
39
|
+
strategyId: string;
|
|
40
|
+
runs: TypedHealthCheckRun<TResult>[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Context for aggregated bucket data visualization.
|
|
45
|
+
*/
|
|
46
|
+
export interface AggregatedDiagramContext<TAggregatedResult = unknown> {
|
|
47
|
+
type: "aggregated";
|
|
48
|
+
systemId: string;
|
|
49
|
+
configurationId: string;
|
|
50
|
+
strategyId: string;
|
|
51
|
+
buckets: TypedAggregatedBucket<TAggregatedResult>[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Discriminated union context for diagram slots.
|
|
56
|
+
* Platform provides either raw runs or aggregated buckets based on date range.
|
|
57
|
+
*/
|
|
58
|
+
export type HealthCheckDiagramSlotContext =
|
|
59
|
+
| RawDiagramContext
|
|
60
|
+
| AggregatedDiagramContext;
|
|
61
|
+
|
|
62
|
+
// =============================================================================
|
|
63
|
+
// SLOT DEFINITION
|
|
64
|
+
// =============================================================================
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Extension slot for custom health check diagrams.
|
|
68
|
+
* Strategy plugins can contribute their own visualizations for check results.
|
|
69
|
+
*/
|
|
70
|
+
export const HealthCheckDiagramSlot = createSlot<HealthCheckDiagramSlotContext>(
|
|
71
|
+
"healthcheck.diagram"
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// =============================================================================
|
|
75
|
+
// FALLBACK COMPONENT
|
|
76
|
+
// =============================================================================
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Fallback shown when a strategy doesn't provide an aggregated component.
|
|
80
|
+
*/
|
|
81
|
+
function AggregatedFallback() {
|
|
82
|
+
return (
|
|
83
|
+
<div className="text-sm text-muted-foreground p-4 text-center border border-dashed rounded-md">
|
|
84
|
+
Strategy does not support aggregated visualization.
|
|
85
|
+
<br />
|
|
86
|
+
Select a shorter time range for detailed per-run data.
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// =============================================================================
|
|
92
|
+
// DIAGRAM EXTENSION FACTORY
|
|
93
|
+
// =============================================================================
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Factory that creates a pre-typed diagram extension helper for a strategy.
|
|
97
|
+
* Strategies call this once in their common package to get a typed helper.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```tsx
|
|
101
|
+
* // In @checkstack/healthcheck-http-common
|
|
102
|
+
* export const createHttpDiagramExtension = createDiagramExtensionFactory<
|
|
103
|
+
* HttpResult,
|
|
104
|
+
* HttpAggregatedResult
|
|
105
|
+
* >(httpCheckMetadata);
|
|
106
|
+
*
|
|
107
|
+
* // In @checkstack/healthcheck-http-frontend
|
|
108
|
+
* createHttpDiagramExtension({
|
|
109
|
+
* id: "http-check.response-chart",
|
|
110
|
+
* rawComponent: HttpRunsChart,
|
|
111
|
+
* aggregatedComponent: HttpAggregatedChart, // optional
|
|
112
|
+
* });
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export function createDiagramExtensionFactory<
|
|
116
|
+
TResult = unknown,
|
|
117
|
+
TAggregatedResult = unknown
|
|
118
|
+
>(strategyMetadata: PluginMetadata) {
|
|
119
|
+
return function createDiagramExtension(options: {
|
|
120
|
+
id: string;
|
|
121
|
+
/** Component for raw per-run data (required) */
|
|
122
|
+
rawComponent: React.ComponentType<RawDiagramContext<TResult>>;
|
|
123
|
+
/** Component for aggregated bucket data (optional) */
|
|
124
|
+
aggregatedComponent?: React.ComponentType<
|
|
125
|
+
AggregatedDiagramContext<TAggregatedResult>
|
|
126
|
+
>;
|
|
127
|
+
}) {
|
|
128
|
+
return createSlotExtension(HealthCheckDiagramSlot, {
|
|
129
|
+
id: options.id,
|
|
130
|
+
component: (ctx: HealthCheckDiagramSlotContext) => {
|
|
131
|
+
// Only render for matching strategy
|
|
132
|
+
if (ctx.strategyId !== strategyMetadata.pluginId) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (ctx.type === "raw") {
|
|
137
|
+
const RawComponent = options.rawComponent;
|
|
138
|
+
return <RawComponent {...(ctx as RawDiagramContext<TResult>)} />;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (options.aggregatedComponent) {
|
|
142
|
+
const AggComponent = options.aggregatedComponent;
|
|
143
|
+
return (
|
|
144
|
+
<AggComponent
|
|
145
|
+
{...(ctx as AggregatedDiagramContext<TAggregatedResult>)}
|
|
146
|
+
/>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Fallback if no aggregated component provided
|
|
151
|
+
return <AggregatedFallback />;
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// =============================================================================
|
|
158
|
+
// LEGACY API (for backwards compatibility)
|
|
159
|
+
// =============================================================================
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @deprecated Use createDiagramExtensionFactory instead for typed metadata.
|
|
163
|
+
*
|
|
164
|
+
* Legacy helper for creating strategy-specific diagram extensions.
|
|
165
|
+
* Wraps the component with strategy ID filtering.
|
|
166
|
+
*/
|
|
167
|
+
export function createStrategyDiagramExtension(options: {
|
|
168
|
+
id: string;
|
|
169
|
+
forStrategies: PluginMetadata | PluginMetadata[];
|
|
170
|
+
component: React.ComponentType<HealthCheckDiagramSlotContext>;
|
|
171
|
+
}) {
|
|
172
|
+
const strategyIds = Array.isArray(options.forStrategies)
|
|
173
|
+
? options.forStrategies.map((m) => m.pluginId)
|
|
174
|
+
: [options.forStrategies.pluginId];
|
|
175
|
+
|
|
176
|
+
return createSlotExtension(HealthCheckDiagramSlot, {
|
|
177
|
+
id: options.id,
|
|
178
|
+
component: (ctx: HealthCheckDiagramSlotContext) => {
|
|
179
|
+
if (!strategyIds.includes(ctx.strategyId)) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
return <options.component {...ctx} />;
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
}
|