@checkstack/healthcheck-frontend 0.3.0 → 0.4.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 +78 -0
- package/package.json +2 -1
- package/src/api.ts +2 -10
- package/src/auto-charts/useStrategySchemas.ts +39 -48
- package/src/components/HealthCheckHistory.tsx +10 -14
- package/src/components/HealthCheckSystemOverview.tsx +66 -123
- package/src/components/SystemHealthBadge.tsx +36 -27
- package/src/components/SystemHealthCheckAssignment.tsx +191 -210
- package/src/hooks/useCollectors.ts +21 -34
- package/src/hooks/useHealthCheckData.ts +88 -137
- package/src/index.tsx +2 -16
- package/src/pages/HealthCheckConfigPage.tsx +64 -40
- package/src/pages/HealthCheckHistoryDetailPage.tsx +25 -24
- package/src/pages/HealthCheckHistoryPage.tsx +24 -20
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState } from "react";
|
|
2
2
|
import {
|
|
3
|
+
usePluginClient,
|
|
3
4
|
useApi,
|
|
4
5
|
type SlotContext,
|
|
5
6
|
accessApiRef,
|
|
6
7
|
} from "@checkstack/frontend-api";
|
|
7
|
-
import {
|
|
8
|
+
import { HealthCheckApi } from "@checkstack/healthcheck-common";
|
|
8
9
|
import {
|
|
9
10
|
Button,
|
|
10
11
|
Dialog,
|
|
@@ -52,17 +53,19 @@ export const SystemHealthCheckAssignment: React.FC<Props> = ({
|
|
|
52
53
|
systemId,
|
|
53
54
|
systemName: _systemName,
|
|
54
55
|
}) => {
|
|
55
|
-
const
|
|
56
|
+
const healthCheckClient = usePluginClient(HealthCheckApi);
|
|
56
57
|
const accessApi = useApi(accessApiRef);
|
|
57
58
|
const { allowed: canManage } = accessApi.useAccess(
|
|
58
59
|
healthCheckAccess.configuration.manage
|
|
59
60
|
);
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const [saving, setSaving] = useState(false);
|
|
61
|
+
const toast = useToast();
|
|
62
|
+
|
|
63
|
+
// UI state
|
|
64
64
|
const [isOpen, setIsOpen] = useState(false);
|
|
65
65
|
const [selectedPanel, setSelectedPanel] = useState<SelectedPanel>();
|
|
66
|
+
const [localThresholds, setLocalThresholds] = useState<
|
|
67
|
+
Record<string, StateThresholds>
|
|
68
|
+
>({});
|
|
66
69
|
const [retentionData, setRetentionData] = useState<
|
|
67
70
|
Record<
|
|
68
71
|
string,
|
|
@@ -71,82 +74,119 @@ export const SystemHealthCheckAssignment: React.FC<Props> = ({
|
|
|
71
74
|
hourlyRetentionDays: number;
|
|
72
75
|
dailyRetentionDays: number;
|
|
73
76
|
isCustom: boolean;
|
|
74
|
-
loading: boolean;
|
|
75
77
|
}
|
|
76
78
|
>
|
|
77
79
|
>({});
|
|
78
|
-
const toast = useToast();
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
toast.error(message);
|
|
94
|
-
} finally {
|
|
95
|
-
setLoading(false);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
81
|
+
// Query: Fetch configurations
|
|
82
|
+
const { data: configurationsData, isLoading: configsLoading } =
|
|
83
|
+
healthCheckClient.getConfigurations.useQuery({}, { enabled: isOpen });
|
|
84
|
+
|
|
85
|
+
// Query: Fetch associations
|
|
86
|
+
const {
|
|
87
|
+
data: associations = [],
|
|
88
|
+
isLoading: associationsLoading,
|
|
89
|
+
refetch: refetchAssociations,
|
|
90
|
+
} = healthCheckClient.getSystemAssociations.useQuery(
|
|
91
|
+
{ systemId },
|
|
92
|
+
{ enabled: true }
|
|
93
|
+
);
|
|
98
94
|
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
95
|
+
// Query: Fetch retention config for selected panel
|
|
96
|
+
const selectedConfigId =
|
|
97
|
+
selectedPanel?.panel === "retention" ? selectedPanel.configId : undefined;
|
|
98
|
+
const { data: retentionConfigData } =
|
|
99
|
+
healthCheckClient.getRetentionConfig.useQuery(
|
|
100
|
+
{ systemId, configurationId: selectedConfigId ?? "" },
|
|
101
|
+
{ enabled: !!selectedConfigId && !retentionData[selectedConfigId] }
|
|
102
|
+
);
|
|
103
103
|
|
|
104
|
-
//
|
|
105
|
-
useEffect(() => {
|
|
106
|
-
if (
|
|
107
|
-
|
|
104
|
+
// Update retention data when fetched
|
|
105
|
+
React.useEffect(() => {
|
|
106
|
+
if (
|
|
107
|
+
retentionConfigData &&
|
|
108
|
+
selectedConfigId &&
|
|
109
|
+
!retentionData[selectedConfigId]
|
|
110
|
+
) {
|
|
111
|
+
setRetentionData((prev) => ({
|
|
112
|
+
...prev,
|
|
113
|
+
[selectedConfigId]: {
|
|
114
|
+
rawRetentionDays:
|
|
115
|
+
retentionConfigData.retentionConfig?.rawRetentionDays ??
|
|
116
|
+
DEFAULT_RETENTION_CONFIG.rawRetentionDays,
|
|
117
|
+
hourlyRetentionDays:
|
|
118
|
+
retentionConfigData.retentionConfig?.hourlyRetentionDays ??
|
|
119
|
+
DEFAULT_RETENTION_CONFIG.hourlyRetentionDays,
|
|
120
|
+
dailyRetentionDays:
|
|
121
|
+
retentionConfigData.retentionConfig?.dailyRetentionDays ??
|
|
122
|
+
DEFAULT_RETENTION_CONFIG.dailyRetentionDays,
|
|
123
|
+
isCustom: !!retentionConfigData.retentionConfig,
|
|
124
|
+
},
|
|
125
|
+
}));
|
|
108
126
|
}
|
|
109
|
-
}, [
|
|
127
|
+
}, [retentionConfigData, selectedConfigId, retentionData]);
|
|
128
|
+
|
|
129
|
+
// Mutation: Associate system
|
|
130
|
+
const associateMutation = healthCheckClient.associateSystem.useMutation({
|
|
131
|
+
onSuccess: () => {
|
|
132
|
+
void refetchAssociations();
|
|
133
|
+
},
|
|
134
|
+
onError: (error) => {
|
|
135
|
+
toast.error(error instanceof Error ? error.message : "Failed to update");
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Mutation: Disassociate system
|
|
140
|
+
const disassociateMutation = healthCheckClient.disassociateSystem.useMutation(
|
|
141
|
+
{
|
|
142
|
+
onSuccess: () => {
|
|
143
|
+
void refetchAssociations();
|
|
144
|
+
},
|
|
145
|
+
onError: (error) => {
|
|
146
|
+
toast.error(
|
|
147
|
+
error instanceof Error ? error.message : "Failed to update"
|
|
148
|
+
);
|
|
149
|
+
},
|
|
150
|
+
}
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// Mutation: Update retention config
|
|
154
|
+
const updateRetentionMutation =
|
|
155
|
+
healthCheckClient.updateRetentionConfig.useMutation({
|
|
156
|
+
onSuccess: () => {
|
|
157
|
+
toast.success("Retention settings saved");
|
|
158
|
+
setSelectedPanel(undefined);
|
|
159
|
+
},
|
|
160
|
+
onError: (error) => {
|
|
161
|
+
toast.error(error instanceof Error ? error.message : "Failed to save");
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const configs = configurationsData?.configurations ?? [];
|
|
166
|
+
const loading = configsLoading || associationsLoading;
|
|
167
|
+
const saving =
|
|
168
|
+
associateMutation.isPending ||
|
|
169
|
+
disassociateMutation.isPending ||
|
|
170
|
+
updateRetentionMutation.isPending;
|
|
110
171
|
|
|
111
|
-
const handleToggleAssignment =
|
|
172
|
+
const handleToggleAssignment = (
|
|
112
173
|
configId: string,
|
|
113
174
|
isCurrentlyAssigned: boolean
|
|
114
175
|
) => {
|
|
115
176
|
const config = configs.find((c) => c.id === configId);
|
|
116
177
|
if (!config) return;
|
|
117
178
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
configurationId: configId,
|
|
130
|
-
enabled: true,
|
|
131
|
-
stateThresholds: DEFAULT_STATE_THRESHOLDS,
|
|
132
|
-
},
|
|
133
|
-
});
|
|
134
|
-
setAssociations((prev) => [
|
|
135
|
-
...prev,
|
|
136
|
-
{
|
|
137
|
-
configurationId: configId,
|
|
138
|
-
configurationName: config.name,
|
|
139
|
-
enabled: true,
|
|
140
|
-
stateThresholds: DEFAULT_STATE_THRESHOLDS,
|
|
141
|
-
},
|
|
142
|
-
]);
|
|
143
|
-
}
|
|
144
|
-
} catch (error) {
|
|
145
|
-
const message =
|
|
146
|
-
error instanceof Error ? error.message : "Failed to update";
|
|
147
|
-
toast.error(message);
|
|
148
|
-
} finally {
|
|
149
|
-
setSaving(false);
|
|
179
|
+
if (isCurrentlyAssigned) {
|
|
180
|
+
disassociateMutation.mutate({ systemId, configId });
|
|
181
|
+
} else {
|
|
182
|
+
associateMutation.mutate({
|
|
183
|
+
systemId,
|
|
184
|
+
body: {
|
|
185
|
+
configurationId: configId,
|
|
186
|
+
enabled: true,
|
|
187
|
+
stateThresholds: DEFAULT_STATE_THRESHOLDS,
|
|
188
|
+
},
|
|
189
|
+
});
|
|
150
190
|
}
|
|
151
191
|
};
|
|
152
192
|
|
|
@@ -154,43 +194,103 @@ export const SystemHealthCheckAssignment: React.FC<Props> = ({
|
|
|
154
194
|
configId: string,
|
|
155
195
|
thresholds: StateThresholds
|
|
156
196
|
) => {
|
|
157
|
-
|
|
158
|
-
prev
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
: a
|
|
162
|
-
)
|
|
163
|
-
);
|
|
197
|
+
setLocalThresholds((prev) => ({
|
|
198
|
+
...prev,
|
|
199
|
+
[configId]: thresholds,
|
|
200
|
+
}));
|
|
164
201
|
};
|
|
165
202
|
|
|
166
|
-
const handleSaveThresholds =
|
|
203
|
+
const handleSaveThresholds = (configId: string) => {
|
|
167
204
|
const assoc = associations.find((a) => a.configurationId === configId);
|
|
205
|
+
const thresholds = localThresholds[configId] ?? assoc?.stateThresholds;
|
|
168
206
|
if (!assoc) return;
|
|
169
207
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
await api.associateSystem({
|
|
208
|
+
associateMutation.mutate(
|
|
209
|
+
{
|
|
173
210
|
systemId,
|
|
174
211
|
body: {
|
|
175
212
|
configurationId: configId,
|
|
176
213
|
enabled: assoc.enabled,
|
|
177
|
-
stateThresholds:
|
|
214
|
+
stateThresholds: thresholds,
|
|
178
215
|
},
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
onSuccess: () => {
|
|
219
|
+
toast.success("Thresholds saved");
|
|
220
|
+
setSelectedPanel(undefined);
|
|
221
|
+
setLocalThresholds((prev) => {
|
|
222
|
+
const next = { ...prev };
|
|
223
|
+
delete next[configId];
|
|
224
|
+
return next;
|
|
225
|
+
});
|
|
226
|
+
},
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const handleSaveRetention = (configId: string) => {
|
|
232
|
+
const data = retentionData[configId];
|
|
233
|
+
if (!data) return;
|
|
234
|
+
|
|
235
|
+
updateRetentionMutation.mutate({
|
|
236
|
+
systemId,
|
|
237
|
+
configurationId: configId,
|
|
238
|
+
retentionConfig: {
|
|
239
|
+
rawRetentionDays: data.rawRetentionDays,
|
|
240
|
+
hourlyRetentionDays: data.hourlyRetentionDays,
|
|
241
|
+
dailyRetentionDays: data.dailyRetentionDays,
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const handleResetRetention = (configId: string) => {
|
|
247
|
+
updateRetentionMutation.mutate(
|
|
248
|
+
{
|
|
249
|
+
systemId,
|
|
250
|
+
configurationId: configId,
|
|
251
|
+
// eslint-disable-next-line unicorn/no-null -- RPC contract uses nullable()
|
|
252
|
+
retentionConfig: null,
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
onSuccess: () => {
|
|
256
|
+
setRetentionData((prev) => ({
|
|
257
|
+
...prev,
|
|
258
|
+
[configId]: {
|
|
259
|
+
rawRetentionDays: DEFAULT_RETENTION_CONFIG.rawRetentionDays,
|
|
260
|
+
hourlyRetentionDays: DEFAULT_RETENTION_CONFIG.hourlyRetentionDays,
|
|
261
|
+
dailyRetentionDays: DEFAULT_RETENTION_CONFIG.dailyRetentionDays,
|
|
262
|
+
isCustom: false,
|
|
263
|
+
},
|
|
264
|
+
}));
|
|
265
|
+
toast.success("Reset to defaults");
|
|
266
|
+
},
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const updateRetentionField = (
|
|
272
|
+
configId: string,
|
|
273
|
+
field: string,
|
|
274
|
+
value: number
|
|
275
|
+
) => {
|
|
276
|
+
setRetentionData((prev) => ({
|
|
277
|
+
...prev,
|
|
278
|
+
[configId]: { ...prev[configId], [field]: value, isCustom: true },
|
|
279
|
+
}));
|
|
188
280
|
};
|
|
189
281
|
|
|
190
282
|
const assignedIds = associations.map((a) => a.configurationId);
|
|
191
283
|
|
|
284
|
+
const getEffectiveThresholds = (assoc: AssociationState): StateThresholds => {
|
|
285
|
+
return (
|
|
286
|
+
localThresholds[assoc.configurationId] ??
|
|
287
|
+
assoc.stateThresholds ??
|
|
288
|
+
DEFAULT_STATE_THRESHOLDS
|
|
289
|
+
);
|
|
290
|
+
};
|
|
291
|
+
|
|
192
292
|
const renderThresholdEditor = (assoc: AssociationState) => {
|
|
193
|
-
const thresholds = assoc
|
|
293
|
+
const thresholds = getEffectiveThresholds(assoc);
|
|
194
294
|
|
|
195
295
|
return (
|
|
196
296
|
<div className="mt-4 space-y-4">
|
|
@@ -455,129 +555,10 @@ export const SystemHealthCheckAssignment: React.FC<Props> = ({
|
|
|
455
555
|
);
|
|
456
556
|
};
|
|
457
557
|
|
|
458
|
-
// Load retention data when retention panel is expanded
|
|
459
|
-
const loadRetentionConfig = async (configId: string) => {
|
|
460
|
-
if (retentionData[configId]) return; // Already loaded
|
|
461
|
-
|
|
462
|
-
setRetentionData((prev) => ({
|
|
463
|
-
...prev,
|
|
464
|
-
[configId]: {
|
|
465
|
-
rawRetentionDays: DEFAULT_RETENTION_CONFIG.rawRetentionDays,
|
|
466
|
-
hourlyRetentionDays: DEFAULT_RETENTION_CONFIG.hourlyRetentionDays,
|
|
467
|
-
dailyRetentionDays: DEFAULT_RETENTION_CONFIG.dailyRetentionDays,
|
|
468
|
-
isCustom: false,
|
|
469
|
-
loading: true,
|
|
470
|
-
},
|
|
471
|
-
}));
|
|
472
|
-
|
|
473
|
-
try {
|
|
474
|
-
const response = await api.getRetentionConfig({
|
|
475
|
-
systemId,
|
|
476
|
-
configurationId: configId,
|
|
477
|
-
});
|
|
478
|
-
setRetentionData((prev) => ({
|
|
479
|
-
...prev,
|
|
480
|
-
[configId]: {
|
|
481
|
-
rawRetentionDays:
|
|
482
|
-
response.retentionConfig?.rawRetentionDays ??
|
|
483
|
-
DEFAULT_RETENTION_CONFIG.rawRetentionDays,
|
|
484
|
-
hourlyRetentionDays:
|
|
485
|
-
response.retentionConfig?.hourlyRetentionDays ??
|
|
486
|
-
DEFAULT_RETENTION_CONFIG.hourlyRetentionDays,
|
|
487
|
-
dailyRetentionDays:
|
|
488
|
-
response.retentionConfig?.dailyRetentionDays ??
|
|
489
|
-
DEFAULT_RETENTION_CONFIG.dailyRetentionDays,
|
|
490
|
-
isCustom: !!response.retentionConfig,
|
|
491
|
-
loading: false,
|
|
492
|
-
},
|
|
493
|
-
}));
|
|
494
|
-
} catch {
|
|
495
|
-
setRetentionData((prev) => ({
|
|
496
|
-
...prev,
|
|
497
|
-
[configId]: { ...prev[configId], loading: false },
|
|
498
|
-
}));
|
|
499
|
-
}
|
|
500
|
-
};
|
|
501
|
-
|
|
502
|
-
const handleSaveRetention = async (configId: string) => {
|
|
503
|
-
const data = retentionData[configId];
|
|
504
|
-
if (!data) return;
|
|
505
|
-
|
|
506
|
-
setSaving(true);
|
|
507
|
-
try {
|
|
508
|
-
await api.updateRetentionConfig({
|
|
509
|
-
systemId,
|
|
510
|
-
configurationId: configId,
|
|
511
|
-
retentionConfig: {
|
|
512
|
-
rawRetentionDays: data.rawRetentionDays,
|
|
513
|
-
hourlyRetentionDays: data.hourlyRetentionDays,
|
|
514
|
-
dailyRetentionDays: data.dailyRetentionDays,
|
|
515
|
-
},
|
|
516
|
-
});
|
|
517
|
-
toast.success("Retention settings saved");
|
|
518
|
-
setSelectedPanel(undefined);
|
|
519
|
-
} catch (error) {
|
|
520
|
-
const message = error instanceof Error ? error.message : "Failed to save";
|
|
521
|
-
toast.error(message);
|
|
522
|
-
} finally {
|
|
523
|
-
setSaving(false);
|
|
524
|
-
}
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
const handleResetRetention = async (configId: string) => {
|
|
528
|
-
setSaving(true);
|
|
529
|
-
try {
|
|
530
|
-
await api.updateRetentionConfig({
|
|
531
|
-
systemId,
|
|
532
|
-
configurationId: configId,
|
|
533
|
-
// eslint-disable-next-line unicorn/no-null -- RPC contract uses nullable()
|
|
534
|
-
retentionConfig: null,
|
|
535
|
-
});
|
|
536
|
-
setRetentionData((prev) => ({
|
|
537
|
-
...prev,
|
|
538
|
-
[configId]: {
|
|
539
|
-
rawRetentionDays: DEFAULT_RETENTION_CONFIG.rawRetentionDays,
|
|
540
|
-
hourlyRetentionDays: DEFAULT_RETENTION_CONFIG.hourlyRetentionDays,
|
|
541
|
-
dailyRetentionDays: DEFAULT_RETENTION_CONFIG.dailyRetentionDays,
|
|
542
|
-
isCustom: false,
|
|
543
|
-
loading: false,
|
|
544
|
-
},
|
|
545
|
-
}));
|
|
546
|
-
toast.success("Reset to defaults");
|
|
547
|
-
} catch (error) {
|
|
548
|
-
const message =
|
|
549
|
-
error instanceof Error ? error.message : "Failed to reset";
|
|
550
|
-
toast.error(message);
|
|
551
|
-
} finally {
|
|
552
|
-
setSaving(false);
|
|
553
|
-
}
|
|
554
|
-
};
|
|
555
|
-
|
|
556
|
-
const updateRetentionField = (
|
|
557
|
-
configId: string,
|
|
558
|
-
field: string,
|
|
559
|
-
value: number
|
|
560
|
-
) => {
|
|
561
|
-
setRetentionData((prev) => ({
|
|
562
|
-
...prev,
|
|
563
|
-
[configId]: { ...prev[configId], [field]: value, isCustom: true },
|
|
564
|
-
}));
|
|
565
|
-
};
|
|
566
|
-
|
|
567
558
|
const renderRetentionEditor = (configId: string) => {
|
|
568
559
|
const data = retentionData[configId];
|
|
569
560
|
|
|
570
|
-
// Trigger load if not loaded
|
|
571
561
|
if (!data) {
|
|
572
|
-
loadRetentionConfig(configId);
|
|
573
|
-
return (
|
|
574
|
-
<div className="mt-4 flex justify-center py-4">
|
|
575
|
-
<LoadingSpinner />
|
|
576
|
-
</div>
|
|
577
|
-
);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
if (data.loading) {
|
|
581
562
|
return (
|
|
582
563
|
<div className="mt-4 flex justify-center py-4">
|
|
583
564
|
<LoadingSpinner />
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { healthCheckApiRef } from "../api";
|
|
4
|
-
import { CollectorDto } from "@checkstack/healthcheck-common";
|
|
1
|
+
import { usePluginClient } from "@checkstack/frontend-api";
|
|
2
|
+
import { CollectorDto, HealthCheckApi } from "@checkstack/healthcheck-common";
|
|
5
3
|
|
|
6
4
|
interface UseCollectorsResult {
|
|
7
5
|
collectors: CollectorDto[];
|
|
8
6
|
loading: boolean;
|
|
9
7
|
error: Error | undefined;
|
|
10
|
-
refetch: () =>
|
|
8
|
+
refetch: () => void;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
11
|
/**
|
|
@@ -15,38 +13,27 @@ interface UseCollectorsResult {
|
|
|
15
13
|
* @param strategyId - The strategy ID to fetch collectors for
|
|
16
14
|
*/
|
|
17
15
|
export function useCollectors(strategyId: string): UseCollectorsResult {
|
|
18
|
-
const
|
|
19
|
-
const [collectors, setCollectors] = useState<CollectorDto[]>([]);
|
|
20
|
-
const [loading, setLoading] = useState(false);
|
|
21
|
-
const [error, setError] = useState<Error>();
|
|
16
|
+
const healthCheckClient = usePluginClient(HealthCheckApi);
|
|
22
17
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
const {
|
|
19
|
+
data,
|
|
20
|
+
isLoading: loading,
|
|
21
|
+
error: queryError,
|
|
22
|
+
refetch,
|
|
23
|
+
} = healthCheckClient.getCollectors.useQuery(
|
|
24
|
+
{ strategyId },
|
|
25
|
+
{ enabled: !!strategyId }
|
|
26
|
+
);
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const result = await api.getCollectors({ strategyId });
|
|
33
|
-
setCollectors(result);
|
|
34
|
-
} catch (error_) {
|
|
35
|
-
setError(
|
|
36
|
-
error_ instanceof Error
|
|
37
|
-
? error_
|
|
38
|
-
: new Error("Failed to fetch collectors")
|
|
39
|
-
);
|
|
40
|
-
} finally {
|
|
41
|
-
setLoading(false);
|
|
42
|
-
}
|
|
43
|
-
}, [api, strategyId]);
|
|
28
|
+
const collectors = data ?? [];
|
|
29
|
+
const error = queryError instanceof Error ? queryError : undefined;
|
|
44
30
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
return {
|
|
32
|
+
collectors,
|
|
33
|
+
loading,
|
|
34
|
+
error,
|
|
35
|
+
refetch: () => void refetch(),
|
|
36
|
+
};
|
|
50
37
|
}
|
|
51
38
|
|
|
52
39
|
/**
|