@checkstack/healthcheck-frontend 0.11.8 → 0.12.1
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 +64 -0
- package/package.json +5 -5
- package/src/auto-charts/schema-parser.ts +0 -7
- package/src/components/HealthCheckSystemOverview.tsx +2 -66
- package/src/components/SystemHealthCheckAssignment.tsx +4 -4
- package/src/components/editor/CollectorPicker.tsx +129 -0
- package/src/components/editor/CollectorSection.tsx +94 -0
- package/src/components/editor/EditorPanel.tsx +164 -0
- package/src/components/editor/EditorTree.tsx +185 -0
- package/src/components/editor/GeneralSection.tsx +98 -0
- package/src/components/editor/IDEStatusBar.tsx +58 -0
- package/src/hooks/useCollectors.ts +1 -1
- package/src/index.tsx +14 -0
- package/src/pages/HealthCheckConfigPage.tsx +16 -63
- package/src/pages/HealthCheckIDEPage.tsx +382 -0
- package/src/pages/StrategyPickerPage.tsx +157 -0
- package/src/components/HealthCheckEditor.tsx +0 -190
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect } from "react";
|
|
2
|
-
import {
|
|
3
|
-
HealthCheckConfiguration,
|
|
4
|
-
HealthCheckStrategyDto,
|
|
5
|
-
CreateHealthCheckConfiguration,
|
|
6
|
-
CollectorConfigEntry,
|
|
7
|
-
} from "@checkstack/healthcheck-common";
|
|
8
|
-
import {
|
|
9
|
-
Button,
|
|
10
|
-
Input,
|
|
11
|
-
Label,
|
|
12
|
-
PluginConfigForm,
|
|
13
|
-
useToast,
|
|
14
|
-
Dialog,
|
|
15
|
-
DialogContent,
|
|
16
|
-
DialogDescription,
|
|
17
|
-
DialogHeader,
|
|
18
|
-
DialogTitle,
|
|
19
|
-
DialogFooter,
|
|
20
|
-
} from "@checkstack/ui";
|
|
21
|
-
import { useCollectors } from "../hooks/useCollectors";
|
|
22
|
-
import { CollectorList } from "./CollectorList";
|
|
23
|
-
import { TeamAccessEditor } from "@checkstack/auth-frontend";
|
|
24
|
-
|
|
25
|
-
interface HealthCheckEditorProps {
|
|
26
|
-
strategies: HealthCheckStrategyDto[];
|
|
27
|
-
initialData?: HealthCheckConfiguration;
|
|
28
|
-
onSave: (data: CreateHealthCheckConfiguration) => Promise<void>;
|
|
29
|
-
onCancel: () => void;
|
|
30
|
-
open: boolean;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const HealthCheckEditor: React.FC<HealthCheckEditorProps> = ({
|
|
34
|
-
strategies,
|
|
35
|
-
initialData,
|
|
36
|
-
onSave,
|
|
37
|
-
onCancel,
|
|
38
|
-
open,
|
|
39
|
-
}) => {
|
|
40
|
-
const [name, setName] = useState(initialData?.name || "");
|
|
41
|
-
const [strategyId, setStrategyId] = useState(initialData?.strategyId || "");
|
|
42
|
-
const [interval, setInterval] = useState(
|
|
43
|
-
initialData?.intervalSeconds?.toString() || "60",
|
|
44
|
-
);
|
|
45
|
-
const [config, setConfig] = useState<Record<string, unknown>>(
|
|
46
|
-
(initialData?.config as Record<string, unknown>) || {},
|
|
47
|
-
);
|
|
48
|
-
const [collectors, setCollectors] = useState<CollectorConfigEntry[]>(
|
|
49
|
-
initialData?.collectors || [],
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
const toast = useToast();
|
|
53
|
-
const [loading, setLoading] = useState(false);
|
|
54
|
-
const [collectorsValid, setCollectorsValid] = useState(true);
|
|
55
|
-
|
|
56
|
-
// Fetch available collectors for the selected strategy
|
|
57
|
-
const { collectors: availableCollectors, loading: collectorsLoading } =
|
|
58
|
-
useCollectors(strategyId);
|
|
59
|
-
|
|
60
|
-
// Reset form when dialog opens with new data
|
|
61
|
-
useEffect(() => {
|
|
62
|
-
if (open) {
|
|
63
|
-
setName(initialData?.name || "");
|
|
64
|
-
setStrategyId(initialData?.strategyId || "");
|
|
65
|
-
setInterval(initialData?.intervalSeconds?.toString() || "60");
|
|
66
|
-
setConfig((initialData?.config as Record<string, unknown>) || {});
|
|
67
|
-
setCollectors(initialData?.collectors || []);
|
|
68
|
-
}
|
|
69
|
-
}, [open, initialData]);
|
|
70
|
-
|
|
71
|
-
// Clear collectors when strategy changes (new strategy = different collectors)
|
|
72
|
-
const handleStrategyChange = (id: string) => {
|
|
73
|
-
setStrategyId(id);
|
|
74
|
-
setConfig({});
|
|
75
|
-
setCollectors([]);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const handleSave = async (e: React.FormEvent) => {
|
|
79
|
-
e.preventDefault();
|
|
80
|
-
setLoading(true);
|
|
81
|
-
try {
|
|
82
|
-
await onSave({
|
|
83
|
-
name,
|
|
84
|
-
strategyId,
|
|
85
|
-
intervalSeconds: Number.parseInt(interval, 10),
|
|
86
|
-
config,
|
|
87
|
-
collectors, // Always send the array, even if empty, to allow clearing
|
|
88
|
-
});
|
|
89
|
-
} catch (error) {
|
|
90
|
-
const message =
|
|
91
|
-
error instanceof Error ? error.message : "Failed to save health check";
|
|
92
|
-
toast.error(message);
|
|
93
|
-
console.error(error);
|
|
94
|
-
} finally {
|
|
95
|
-
setLoading(false);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<Dialog open={open} onOpenChange={(isOpen) => !isOpen && onCancel()}>
|
|
101
|
-
<DialogContent size="lg">
|
|
102
|
-
<form onSubmit={handleSave}>
|
|
103
|
-
<DialogHeader>
|
|
104
|
-
<DialogTitle>
|
|
105
|
-
{initialData ? "Edit Health Check" : "Create Health Check"}
|
|
106
|
-
</DialogTitle>
|
|
107
|
-
<DialogDescription className="sr-only">
|
|
108
|
-
{initialData
|
|
109
|
-
? "Modify the settings for this health check configuration"
|
|
110
|
-
: "Configure a new health check to monitor your services"}
|
|
111
|
-
</DialogDescription>
|
|
112
|
-
</DialogHeader>
|
|
113
|
-
|
|
114
|
-
<div className="space-y-6 py-4">
|
|
115
|
-
<div className="space-y-2">
|
|
116
|
-
<Label htmlFor="name">Name</Label>
|
|
117
|
-
<Input
|
|
118
|
-
id="name"
|
|
119
|
-
value={name}
|
|
120
|
-
onChange={(e) => setName(e.target.value)}
|
|
121
|
-
required
|
|
122
|
-
/>
|
|
123
|
-
</div>
|
|
124
|
-
|
|
125
|
-
<div className="space-y-2">
|
|
126
|
-
<Label htmlFor="interval">Interval (seconds)</Label>
|
|
127
|
-
<Input
|
|
128
|
-
id="interval"
|
|
129
|
-
type="number"
|
|
130
|
-
min="1"
|
|
131
|
-
value={interval}
|
|
132
|
-
onChange={(e) => setInterval(e.target.value)}
|
|
133
|
-
required
|
|
134
|
-
/>
|
|
135
|
-
{Number.parseInt(interval, 10) < 60 && (
|
|
136
|
-
<p className="text-sm text-amber-600 dark:text-amber-400">
|
|
137
|
-
⚠️ Sub-minute intervals generate large amounts of data and may
|
|
138
|
-
impact chart loading performance. Consider using intervals of
|
|
139
|
-
60 seconds or more or drastically reduce the retention period
|
|
140
|
-
for raw data.
|
|
141
|
-
</p>
|
|
142
|
-
)}
|
|
143
|
-
</div>
|
|
144
|
-
|
|
145
|
-
<PluginConfigForm
|
|
146
|
-
label="Strategy"
|
|
147
|
-
plugins={strategies}
|
|
148
|
-
selectedPluginId={strategyId}
|
|
149
|
-
onPluginChange={handleStrategyChange}
|
|
150
|
-
config={config}
|
|
151
|
-
onConfigChange={setConfig}
|
|
152
|
-
disabled={!!initialData}
|
|
153
|
-
/>
|
|
154
|
-
|
|
155
|
-
{/* Collector Configuration Section */}
|
|
156
|
-
{strategyId && (
|
|
157
|
-
<CollectorList
|
|
158
|
-
strategyId={strategyId}
|
|
159
|
-
availableCollectors={availableCollectors}
|
|
160
|
-
configuredCollectors={collectors}
|
|
161
|
-
onChange={setCollectors}
|
|
162
|
-
loading={collectorsLoading}
|
|
163
|
-
onValidChange={setCollectorsValid}
|
|
164
|
-
/>
|
|
165
|
-
)}
|
|
166
|
-
|
|
167
|
-
{/* Team Access Editor - only shown for existing configurations */}
|
|
168
|
-
{initialData?.id && (
|
|
169
|
-
<TeamAccessEditor
|
|
170
|
-
resourceType="healthcheck.configuration"
|
|
171
|
-
resourceId={initialData.id}
|
|
172
|
-
compact
|
|
173
|
-
expanded
|
|
174
|
-
/>
|
|
175
|
-
)}
|
|
176
|
-
</div>
|
|
177
|
-
|
|
178
|
-
<DialogFooter>
|
|
179
|
-
<Button type="button" variant="outline" onClick={onCancel}>
|
|
180
|
-
Cancel
|
|
181
|
-
</Button>
|
|
182
|
-
<Button type="submit" disabled={loading || !collectorsValid}>
|
|
183
|
-
{loading ? "Saving..." : "Save"}
|
|
184
|
-
</Button>
|
|
185
|
-
</DialogFooter>
|
|
186
|
-
</form>
|
|
187
|
-
</DialogContent>
|
|
188
|
-
</Dialog>
|
|
189
|
-
);
|
|
190
|
-
};
|