@checkstack/healthcheck-frontend 0.12.0 → 0.13.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/CHANGELOG.md +103 -0
- package/package.json +12 -11
- package/src/auto-charts/schema-parser.ts +0 -7
- package/src/components/HealthCheckRunsTable.tsx +19 -1
- package/src/components/HealthCheckSystemOverview.tsx +80 -71
- package/src/components/SystemHealthCheckAssignment.tsx +33 -824
- package/src/components/assignments/AssignmentTree.tsx +123 -0
- package/src/components/assignments/ExecutionPanel.tsx +135 -0
- package/src/components/assignments/GeneralPanel.tsx +100 -0
- package/src/components/assignments/RetentionPanel.tsx +157 -0
- package/src/components/assignments/ThresholdsPanel.tsx +254 -0
- package/src/components/editor/EditorTree.tsx +10 -75
- package/src/components/editor/IDEStatusBar.tsx +5 -58
- package/src/hooks/useCollectors.ts +1 -1
- package/src/hooks/useHealthCheckData.ts +4 -0
- package/src/index.tsx +7 -0
- package/src/pages/AssignmentIDEPage.tsx +477 -0
- package/src/pages/HealthCheckConfigPage.tsx +4 -4
- package/src/pages/HealthCheckHistoryDetailPage.tsx +53 -6
- package/src/pages/HealthCheckIDEPage.tsx +10 -18
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { StateThresholds } from "@checkstack/healthcheck-common";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
Input,
|
|
7
|
+
Label,
|
|
8
|
+
Select,
|
|
9
|
+
SelectContent,
|
|
10
|
+
SelectItem,
|
|
11
|
+
SelectTrigger,
|
|
12
|
+
SelectValue,
|
|
13
|
+
Tooltip,
|
|
14
|
+
} from "@checkstack/ui";
|
|
15
|
+
|
|
16
|
+
interface ThresholdsPanelProps {
|
|
17
|
+
thresholds: StateThresholds;
|
|
18
|
+
onChange: (thresholds: StateThresholds) => void;
|
|
19
|
+
onSave: () => void;
|
|
20
|
+
saving: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Panel for configuring health check evaluation thresholds.
|
|
25
|
+
* Supports two modes: consecutive (streak-based) and window (count in last N runs).
|
|
26
|
+
*/
|
|
27
|
+
export const ThresholdsPanel: React.FC<ThresholdsPanelProps> = ({
|
|
28
|
+
thresholds,
|
|
29
|
+
onChange,
|
|
30
|
+
onSave,
|
|
31
|
+
saving,
|
|
32
|
+
}) => {
|
|
33
|
+
return (
|
|
34
|
+
<div className="p-6 space-y-4">
|
|
35
|
+
<div>
|
|
36
|
+
<h3 className="text-sm font-semibold">State Thresholds</h3>
|
|
37
|
+
<p className="text-xs text-muted-foreground mt-1">
|
|
38
|
+
Configure how health check results determine the system's status.
|
|
39
|
+
</p>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
{/* Mode Selector */}
|
|
43
|
+
<div className="p-4 bg-muted/50 rounded-lg border">
|
|
44
|
+
<div className="flex items-center gap-2 mb-2">
|
|
45
|
+
<Label className="text-sm font-medium">Evaluation Mode</Label>
|
|
46
|
+
<Tooltip content="How health status is calculated based on check results" />
|
|
47
|
+
</div>
|
|
48
|
+
<Select
|
|
49
|
+
value={thresholds.mode}
|
|
50
|
+
onValueChange={(value: "consecutive" | "window") => {
|
|
51
|
+
if (value === "consecutive") {
|
|
52
|
+
onChange({
|
|
53
|
+
mode: "consecutive",
|
|
54
|
+
healthy: { minSuccessCount: 1 },
|
|
55
|
+
degraded: { minFailureCount: 2 },
|
|
56
|
+
unhealthy: { minFailureCount: 5 },
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
onChange({
|
|
60
|
+
mode: "window",
|
|
61
|
+
windowSize: 10,
|
|
62
|
+
degraded: { minFailureCount: 3 },
|
|
63
|
+
unhealthy: { minFailureCount: 7 },
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<SelectTrigger className="w-full">
|
|
69
|
+
<SelectValue />
|
|
70
|
+
</SelectTrigger>
|
|
71
|
+
<SelectContent>
|
|
72
|
+
<SelectItem value="consecutive">
|
|
73
|
+
Consecutive (streak-based)
|
|
74
|
+
</SelectItem>
|
|
75
|
+
<SelectItem value="window">
|
|
76
|
+
Window (count in last N runs)
|
|
77
|
+
</SelectItem>
|
|
78
|
+
</SelectContent>
|
|
79
|
+
</Select>
|
|
80
|
+
<p className="text-xs text-muted-foreground mt-2">
|
|
81
|
+
{thresholds.mode === "consecutive"
|
|
82
|
+
? "Status changes when a streak of consecutive results is reached."
|
|
83
|
+
: "Status is based on how many failures occur within a rolling window."}
|
|
84
|
+
</p>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
{/* Threshold Cards */}
|
|
88
|
+
{thresholds.mode === "consecutive" ? (
|
|
89
|
+
<div className="space-y-3">
|
|
90
|
+
<ThresholdCard
|
|
91
|
+
status="healthy"
|
|
92
|
+
label="Healthy"
|
|
93
|
+
tooltip="System returns to healthy after this many consecutive successful checks"
|
|
94
|
+
value={thresholds.healthy.minSuccessCount}
|
|
95
|
+
suffix="consecutive ✓"
|
|
96
|
+
onChange={(v) =>
|
|
97
|
+
onChange({ ...thresholds, healthy: { minSuccessCount: v } })
|
|
98
|
+
}
|
|
99
|
+
/>
|
|
100
|
+
<ThresholdCard
|
|
101
|
+
status="warning"
|
|
102
|
+
label="Degraded"
|
|
103
|
+
tooltip="System becomes degraded after this many consecutive failures"
|
|
104
|
+
value={thresholds.degraded.minFailureCount}
|
|
105
|
+
suffix="consecutive ✗"
|
|
106
|
+
onChange={(v) =>
|
|
107
|
+
onChange({ ...thresholds, degraded: { minFailureCount: v } })
|
|
108
|
+
}
|
|
109
|
+
/>
|
|
110
|
+
<ThresholdCard
|
|
111
|
+
status="destructive"
|
|
112
|
+
label="Unhealthy"
|
|
113
|
+
tooltip="System becomes unhealthy after this many consecutive failures"
|
|
114
|
+
value={thresholds.unhealthy.minFailureCount}
|
|
115
|
+
suffix="consecutive ✗"
|
|
116
|
+
onChange={(v) =>
|
|
117
|
+
onChange({ ...thresholds, unhealthy: { minFailureCount: v } })
|
|
118
|
+
}
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
) : (
|
|
122
|
+
<div className="space-y-3">
|
|
123
|
+
{/* Window Size */}
|
|
124
|
+
<div className="p-3 rounded-lg border bg-muted/30">
|
|
125
|
+
<div className="flex items-center justify-between">
|
|
126
|
+
<div className="flex items-center gap-2">
|
|
127
|
+
<span className="text-sm font-medium">Window Size</span>
|
|
128
|
+
<Tooltip content="How many recent runs to analyze when calculating status" />
|
|
129
|
+
</div>
|
|
130
|
+
<div className="flex items-center gap-2">
|
|
131
|
+
<Input
|
|
132
|
+
type="number"
|
|
133
|
+
min={3}
|
|
134
|
+
max={100}
|
|
135
|
+
value={thresholds.windowSize}
|
|
136
|
+
onChange={(e) =>
|
|
137
|
+
onChange({
|
|
138
|
+
...thresholds,
|
|
139
|
+
windowSize: Number.parseInt(e.target.value) || 10,
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
className="h-8 w-16 text-center"
|
|
143
|
+
/>
|
|
144
|
+
<span className="text-xs text-muted-foreground">runs</span>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<ThresholdCard
|
|
150
|
+
status="warning"
|
|
151
|
+
label="Degraded"
|
|
152
|
+
tooltip="System becomes degraded when failures in the window reach this count"
|
|
153
|
+
value={thresholds.degraded.minFailureCount}
|
|
154
|
+
prefix="≥"
|
|
155
|
+
suffix="failures"
|
|
156
|
+
onChange={(v) =>
|
|
157
|
+
onChange({ ...thresholds, degraded: { minFailureCount: v } })
|
|
158
|
+
}
|
|
159
|
+
/>
|
|
160
|
+
<ThresholdCard
|
|
161
|
+
status="destructive"
|
|
162
|
+
label="Unhealthy"
|
|
163
|
+
tooltip="System becomes unhealthy when failures in the window reach this count"
|
|
164
|
+
value={thresholds.unhealthy.minFailureCount}
|
|
165
|
+
prefix="≥"
|
|
166
|
+
suffix="failures"
|
|
167
|
+
onChange={(v) =>
|
|
168
|
+
onChange({ ...thresholds, unhealthy: { minFailureCount: v } })
|
|
169
|
+
}
|
|
170
|
+
/>
|
|
171
|
+
</div>
|
|
172
|
+
)}
|
|
173
|
+
|
|
174
|
+
{/* Save Button */}
|
|
175
|
+
<div className="flex justify-end pt-2 border-t">
|
|
176
|
+
<Button size="sm" onClick={onSave} disabled={saving}>
|
|
177
|
+
{saving ? "Saving..." : "Save Thresholds"}
|
|
178
|
+
</Button>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// =============================================================================
|
|
185
|
+
// THRESHOLD CARD — Shared sub-component
|
|
186
|
+
// =============================================================================
|
|
187
|
+
|
|
188
|
+
const STATUS_STYLES = {
|
|
189
|
+
healthy: {
|
|
190
|
+
dot: "bg-success",
|
|
191
|
+
text: "text-success",
|
|
192
|
+
border: "border-success/30",
|
|
193
|
+
bg: "bg-success/5",
|
|
194
|
+
},
|
|
195
|
+
warning: {
|
|
196
|
+
dot: "bg-warning",
|
|
197
|
+
text: "text-warning",
|
|
198
|
+
border: "border-warning/30",
|
|
199
|
+
bg: "bg-warning/5",
|
|
200
|
+
},
|
|
201
|
+
destructive: {
|
|
202
|
+
dot: "bg-destructive",
|
|
203
|
+
text: "text-destructive",
|
|
204
|
+
border: "border-destructive/30",
|
|
205
|
+
bg: "bg-destructive/5",
|
|
206
|
+
},
|
|
207
|
+
} as const;
|
|
208
|
+
|
|
209
|
+
function ThresholdCard({
|
|
210
|
+
status,
|
|
211
|
+
label,
|
|
212
|
+
tooltip,
|
|
213
|
+
value,
|
|
214
|
+
prefix,
|
|
215
|
+
suffix,
|
|
216
|
+
onChange,
|
|
217
|
+
}: {
|
|
218
|
+
status: keyof typeof STATUS_STYLES;
|
|
219
|
+
label: string;
|
|
220
|
+
tooltip: string;
|
|
221
|
+
value: number;
|
|
222
|
+
prefix?: string;
|
|
223
|
+
suffix: string;
|
|
224
|
+
onChange: (value: number) => void;
|
|
225
|
+
}) {
|
|
226
|
+
const styles = STATUS_STYLES[status];
|
|
227
|
+
return (
|
|
228
|
+
<div className={`p-3 rounded-lg border ${styles.border} ${styles.bg}`}>
|
|
229
|
+
<div className="flex items-center justify-between">
|
|
230
|
+
<div className="flex items-center gap-2">
|
|
231
|
+
<div className={`h-2 w-2 rounded-full ${styles.dot}`} />
|
|
232
|
+
<span className={`text-sm font-medium ${styles.text}`}>{label}</span>
|
|
233
|
+
<Tooltip content={tooltip} />
|
|
234
|
+
</div>
|
|
235
|
+
<div className="flex items-center gap-2">
|
|
236
|
+
{prefix && (
|
|
237
|
+
<span className="text-xs text-muted-foreground">{prefix}</span>
|
|
238
|
+
)}
|
|
239
|
+
<Input
|
|
240
|
+
type="number"
|
|
241
|
+
min={1}
|
|
242
|
+
value={value}
|
|
243
|
+
onChange={(e) => onChange(Number.parseInt(e.target.value) || 1)}
|
|
244
|
+
className="h-8 w-16 text-center"
|
|
245
|
+
/>
|
|
246
|
+
<span className="text-xs text-muted-foreground w-20">{suffix}</span>
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
</div>
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Re-export DEFAULT_STATE_THRESHOLDS for convenience
|
|
254
|
+
export { DEFAULT_STATE_THRESHOLDS } from "@checkstack/healthcheck-common";
|
|
@@ -5,8 +5,11 @@ import type {
|
|
|
5
5
|
} from "@checkstack/healthcheck-common";
|
|
6
6
|
import { Plus, Settings, Shield, ChevronRight } from "lucide-react";
|
|
7
7
|
import { isBuiltInCollector } from "../../hooks/useCollectors";
|
|
8
|
-
import
|
|
9
|
-
|
|
8
|
+
import {
|
|
9
|
+
IDETreeNode,
|
|
10
|
+
IDETreeSection,
|
|
11
|
+
type ValidationIssue,
|
|
12
|
+
} from "@checkstack/ui";
|
|
10
13
|
|
|
11
14
|
// =============================================================================
|
|
12
15
|
// TYPES
|
|
@@ -28,66 +31,6 @@ interface EditorTreeProps {
|
|
|
28
31
|
strategyId: string;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
// =============================================================================
|
|
32
|
-
// VALIDATION INDICATOR
|
|
33
|
-
// =============================================================================
|
|
34
|
-
|
|
35
|
-
function ValidationDot({ nodeId, issues }: { nodeId: string; issues: ValidationIssue[] }) {
|
|
36
|
-
const nodeIssues = issues.filter((i) => i.nodeId === nodeId);
|
|
37
|
-
if (nodeIssues.length === 0) return;
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<span className="ml-auto flex h-2 w-2 rounded-full bg-destructive shrink-0" />
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// =============================================================================
|
|
45
|
-
// TREE NODE
|
|
46
|
-
// =============================================================================
|
|
47
|
-
|
|
48
|
-
function TreeNode({
|
|
49
|
-
nodeId,
|
|
50
|
-
label,
|
|
51
|
-
icon: Icon,
|
|
52
|
-
selected,
|
|
53
|
-
onClick,
|
|
54
|
-
issues,
|
|
55
|
-
indent = false,
|
|
56
|
-
badge,
|
|
57
|
-
}: {
|
|
58
|
-
nodeId: string;
|
|
59
|
-
label: string;
|
|
60
|
-
icon: React.ElementType;
|
|
61
|
-
selected: boolean;
|
|
62
|
-
onClick: () => void;
|
|
63
|
-
issues: ValidationIssue[];
|
|
64
|
-
indent?: boolean;
|
|
65
|
-
badge?: string;
|
|
66
|
-
}) {
|
|
67
|
-
return (
|
|
68
|
-
<button
|
|
69
|
-
type="button"
|
|
70
|
-
onClick={onClick}
|
|
71
|
-
className={`flex items-center gap-2 w-full px-3 py-2 text-sm text-left transition-colors ${
|
|
72
|
-
indent ? "pl-7" : ""
|
|
73
|
-
} ${
|
|
74
|
-
selected
|
|
75
|
-
? "bg-primary/10 text-primary border-l-2 border-primary"
|
|
76
|
-
: "hover:bg-muted/50 border-l-2 border-transparent"
|
|
77
|
-
}`}
|
|
78
|
-
>
|
|
79
|
-
<Icon className="h-4 w-4 shrink-0 opacity-60" />
|
|
80
|
-
<span className="truncate flex-1">{label}</span>
|
|
81
|
-
{badge && (
|
|
82
|
-
<Badge variant="secondary" className="text-[10px] shrink-0">
|
|
83
|
-
{badge}
|
|
84
|
-
</Badge>
|
|
85
|
-
)}
|
|
86
|
-
<ValidationDot nodeId={nodeId} issues={issues} />
|
|
87
|
-
</button>
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
34
|
// =============================================================================
|
|
92
35
|
// EDITOR TREE
|
|
93
36
|
// =============================================================================
|
|
@@ -111,7 +54,7 @@ export const EditorTree: React.FC<EditorTreeProps> = ({
|
|
|
111
54
|
return (
|
|
112
55
|
<div className="py-2">
|
|
113
56
|
{/* General */}
|
|
114
|
-
<
|
|
57
|
+
<IDETreeNode
|
|
115
58
|
nodeId="general"
|
|
116
59
|
label="General"
|
|
117
60
|
icon={Settings}
|
|
@@ -121,11 +64,7 @@ export const EditorTree: React.FC<EditorTreeProps> = ({
|
|
|
121
64
|
/>
|
|
122
65
|
|
|
123
66
|
{/* Collectors Section Header */}
|
|
124
|
-
<
|
|
125
|
-
<span className="text-[11px] font-semibold text-muted-foreground uppercase tracking-wider">
|
|
126
|
-
Check Items
|
|
127
|
-
</span>
|
|
128
|
-
</div>
|
|
67
|
+
<IDETreeSection label="Check Items" />
|
|
129
68
|
|
|
130
69
|
{/* Configured Collectors */}
|
|
131
70
|
{collectors.map((entry) => {
|
|
@@ -135,7 +74,7 @@ export const EditorTree: React.FC<EditorTreeProps> = ({
|
|
|
135
74
|
const builtIn = isBuiltInCollector(entry.collectorId, strategyId);
|
|
136
75
|
|
|
137
76
|
return (
|
|
138
|
-
<
|
|
77
|
+
<IDETreeNode
|
|
139
78
|
key={entry.id}
|
|
140
79
|
nodeId={`collector:${entry.id}`}
|
|
141
80
|
label={collector?.displayName ?? entry.collectorId}
|
|
@@ -166,13 +105,9 @@ export const EditorTree: React.FC<EditorTreeProps> = ({
|
|
|
166
105
|
)}
|
|
167
106
|
|
|
168
107
|
{/* Access Control */}
|
|
169
|
-
<
|
|
170
|
-
<span className="text-[11px] font-semibold text-muted-foreground uppercase tracking-wider">
|
|
171
|
-
Permissions
|
|
172
|
-
</span>
|
|
173
|
-
</div>
|
|
108
|
+
<IDETreeSection label="Permissions" />
|
|
174
109
|
|
|
175
|
-
<
|
|
110
|
+
<IDETreeNode
|
|
176
111
|
nodeId="access"
|
|
177
112
|
label="Access Control"
|
|
178
113
|
icon={Shield}
|
|
@@ -1,58 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// TYPES
|
|
7
|
-
// =============================================================================
|
|
8
|
-
|
|
9
|
-
export interface ValidationIssue {
|
|
10
|
-
nodeId: TreeNodeId;
|
|
11
|
-
message: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface IDEStatusBarProps {
|
|
15
|
-
issues: ValidationIssue[];
|
|
16
|
-
onIssueClick: (nodeId: TreeNodeId) => void;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// =============================================================================
|
|
20
|
-
// STATUS BAR
|
|
21
|
-
// =============================================================================
|
|
22
|
-
|
|
23
|
-
export const IDEStatusBar: React.FC<IDEStatusBarProps> = ({
|
|
24
|
-
issues,
|
|
25
|
-
onIssueClick,
|
|
26
|
-
}) => {
|
|
27
|
-
if (issues.length === 0) {
|
|
28
|
-
return (
|
|
29
|
-
<div className="flex items-center gap-2 px-4 py-2 mt-2 rounded-md border bg-card text-xs text-muted-foreground">
|
|
30
|
-
<CheckCircle2 className="h-3.5 w-3.5 text-green-500" />
|
|
31
|
-
<span>No issues found</span>
|
|
32
|
-
</div>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<div className="flex items-center gap-3 px-4 py-2 mt-2 rounded-md border bg-card text-xs">
|
|
38
|
-
<div className="flex items-center gap-1.5 text-destructive shrink-0">
|
|
39
|
-
<AlertCircle className="h-3.5 w-3.5" />
|
|
40
|
-
<span className="font-medium">
|
|
41
|
-
{issues.length} {issues.length === 1 ? "issue" : "issues"}
|
|
42
|
-
</span>
|
|
43
|
-
</div>
|
|
44
|
-
<div className="flex items-center gap-2 overflow-x-auto">
|
|
45
|
-
{issues.map((issue, i) => (
|
|
46
|
-
<button
|
|
47
|
-
key={`${issue.nodeId}-${i}`}
|
|
48
|
-
type="button"
|
|
49
|
-
onClick={() => onIssueClick(issue.nodeId)}
|
|
50
|
-
className="text-muted-foreground hover:text-foreground transition-colors whitespace-nowrap underline-offset-2 hover:underline"
|
|
51
|
-
>
|
|
52
|
-
{issue.message}
|
|
53
|
-
</button>
|
|
54
|
-
))}
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
);
|
|
58
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Re-export IDEStatusBar and ValidationIssue from the shared UI package.
|
|
3
|
+
* Kept for backward compatibility — existing imports from this path continue to work.
|
|
4
|
+
*/
|
|
5
|
+
export { IDEStatusBar, type ValidationIssue } from "@checkstack/ui";
|
|
@@ -23,6 +23,8 @@ interface UseHealthCheckDataProps {
|
|
|
23
23
|
startDate: Date;
|
|
24
24
|
endDate: Date;
|
|
25
25
|
};
|
|
26
|
+
/** Filter by source: "local" = core only, satellite UUID = specific satellite, undefined = all */
|
|
27
|
+
sourceFilter?: string;
|
|
26
28
|
/** Whether the date range is a rolling preset (e.g., 'Last 7 days') that should auto-update */
|
|
27
29
|
isRollingPreset?: boolean;
|
|
28
30
|
/** Callback to update the date range (e.g., to refresh endDate to current time) */
|
|
@@ -60,6 +62,7 @@ export function useHealthCheckData({
|
|
|
60
62
|
configurationId,
|
|
61
63
|
strategyId,
|
|
62
64
|
dateRange,
|
|
65
|
+
sourceFilter,
|
|
63
66
|
isRollingPreset = false,
|
|
64
67
|
onDateRangeRefresh,
|
|
65
68
|
}: UseHealthCheckDataProps): UseHealthCheckDataResult {
|
|
@@ -82,6 +85,7 @@ export function useHealthCheckData({
|
|
|
82
85
|
configurationId,
|
|
83
86
|
startDate: dateRange.startDate,
|
|
84
87
|
endDate: dateRange.endDate,
|
|
88
|
+
sourceFilter,
|
|
85
89
|
targetPoints: 500,
|
|
86
90
|
},
|
|
87
91
|
{
|
package/src/index.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import { HealthCheckConfigPage } from "./pages/HealthCheckConfigPage";
|
|
7
7
|
import { StrategyPickerPage } from "./pages/StrategyPickerPage";
|
|
8
8
|
import { HealthCheckIDEPage } from "./pages/HealthCheckIDEPage";
|
|
9
|
+
import { AssignmentIDEPage } from "./pages/AssignmentIDEPage";
|
|
9
10
|
import { HealthCheckHistoryPage } from "./pages/HealthCheckHistoryPage";
|
|
10
11
|
import { HealthCheckHistoryDetailPage } from "./pages/HealthCheckHistoryDetailPage";
|
|
11
12
|
import { HealthCheckMenuItems } from "./components/HealthCheckMenuItems";
|
|
@@ -57,6 +58,12 @@ export default createFrontendPlugin({
|
|
|
57
58
|
title: "Edit Health Check",
|
|
58
59
|
accessRule: healthCheckAccess.configuration.manage,
|
|
59
60
|
},
|
|
61
|
+
{
|
|
62
|
+
route: healthcheckRoutes.routes.assignments,
|
|
63
|
+
element: <AssignmentIDEPage />,
|
|
64
|
+
title: "Health Check Assignments",
|
|
65
|
+
accessRule: healthCheckAccess.configuration.manage,
|
|
66
|
+
},
|
|
60
67
|
{
|
|
61
68
|
route: healthcheckRoutes.routes.history,
|
|
62
69
|
element: <HealthCheckHistoryPage />,
|