@skyhook-io/k8s-ui 1.8.11 → 1.8.12
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/package.json +4 -4
- package/src/components/applications/ApplicationDetail.test.tsx +136 -8
- package/src/components/applications/ApplicationDetail.tsx +1215 -487
- package/src/components/gitops/GitOpsDetailLayout.tsx +13 -3
- package/src/components/gitops/GitOpsTableView.tsx +10 -3
- package/src/components/gitops/SyncOptionsDialog.test.ts +48 -0
- package/src/components/gitops/SyncOptionsDialog.tsx +189 -45
- package/src/components/gitops/insights/ArgoResourceDiff.tsx +172 -0
- package/src/components/gitops/insights/GitOpsInsightViews.tsx +201 -21
- package/src/components/gitops/insights/index.ts +1 -0
- package/src/components/gitops/insights/insights-helpers.test.ts +16 -0
- package/src/components/gitops/insights/insights-helpers.ts +5 -0
- package/src/components/gitops/tree/GitOpsTreeGraph.tsx +5 -0
- package/src/components/issues/IssuesView.tsx +55 -29
- package/src/components/issues/ResourceIssuesSection.test.tsx +33 -1
- package/src/components/issues/ResourceIssuesSection.tsx +21 -1
- package/src/components/issues/severity.ts +1 -0
- package/src/components/resources/renderers/AWSMachineRenderer.tsx +3 -2
- package/src/components/resources/renderers/AWSManagedClusterRenderer.tsx +3 -2
- package/src/components/resources/renderers/AWSManagedControlPlaneRenderer.tsx +3 -2
- package/src/components/resources/renderers/AWSManagedMachinePoolRenderer.tsx +3 -2
- package/src/components/resources/renderers/AzureMachineRenderer.tsx +3 -2
- package/src/components/resources/renderers/AzureManagedControlPlaneRenderer.tsx +3 -2
- package/src/components/resources/renderers/AzureManagedMachinePoolRenderer.tsx +3 -2
- package/src/components/resources/renderers/CAPIClusterRenderer.tsx +3 -2
- package/src/components/resources/renderers/CAPIKubeadmControlPlaneRenderer.tsx +3 -2
- package/src/components/resources/renderers/CAPIMachineDeploymentRenderer.tsx +3 -2
- package/src/components/resources/renderers/CAPIMachineHealthCheckRenderer.tsx +3 -2
- package/src/components/resources/renderers/CAPIMachinePoolRenderer.tsx +3 -2
- package/src/components/resources/renderers/CAPIMachineRenderer.tsx +3 -2
- package/src/components/resources/renderers/CAPIMachineSetRenderer.tsx +3 -2
- package/src/components/resources/renderers/CertificateRenderer.tsx +3 -2
- package/src/components/resources/renderers/CertificateRequestRenderer.tsx +3 -2
- package/src/components/resources/renderers/CompositeRenderer.tsx +3 -2
- package/src/components/resources/renderers/ExternalSecretRenderer.tsx +3 -2
- package/src/components/resources/renderers/GCPMachineRenderer.tsx +3 -2
- package/src/components/resources/renderers/GCPManagedControlPlaneRenderer.tsx +3 -2
- package/src/components/resources/renderers/GCPManagedMachinePoolRenderer.tsx +3 -2
- package/src/components/resources/renderers/GRPCRouteRenderer.tsx +7 -3
- package/src/components/resources/renderers/GatewayClassRenderer.tsx +3 -2
- package/src/components/resources/renderers/HTTPRouteRenderer.tsx +7 -3
- package/src/components/resources/renderers/KarpenterEC2NodeClassRenderer.tsx +3 -2
- package/src/components/resources/renderers/KarpenterNodeClaimRenderer.tsx +3 -2
- package/src/components/resources/renderers/KarpenterNodePoolRenderer.tsx +3 -2
- package/src/components/resources/renderers/KedaScaledJobRenderer.tsx +3 -2
- package/src/components/resources/renderers/KedaScaledObjectRenderer.tsx +3 -2
- package/src/components/resources/renderers/ManagedResourceRenderer.tsx +3 -2
- package/src/components/resources/renderers/PVCRenderer.tsx +3 -2
- package/src/components/resources/renderers/SealedSecretRenderer.tsx +3 -2
- package/src/components/resources/renderers/SecretStoreRenderer.tsx +3 -2
- package/src/components/resources/renderers/SimpleRouteRenderer.tsx +7 -3
- package/src/components/resources/resource-utils-argo.test.ts +18 -1
- package/src/components/resources/resource-utils-argo.ts +8 -0
- package/src/components/shared/ResourceActionsBar.tsx +2 -3
- package/src/components/shared/UnifiedDiff.tsx +51 -0
- package/src/components/shared/index.ts +1 -0
- package/src/components/timeline/TimelineList.tsx +7 -3
- package/src/components/timeline/TimelineToolbarState.test.tsx +24 -0
- package/src/components/topology/TopologyBreadcrumb.tsx +30 -0
- package/src/components/topology/TopologyControls.tsx +3 -1
- package/src/components/topology/TopologyGraph.tsx +76 -90
- package/src/components/topology/TopologyOverlayBar.tsx +30 -0
- package/src/components/topology/TopologySearch.tsx +23 -15
- package/src/components/topology/index.ts +2 -0
- package/src/components/ui/Badge.tsx +1 -1
- package/src/components/ui/SelectMenu.tsx +81 -0
- package/src/components/ui/drawer-components.tsx +9 -6
- package/src/components/ui/index.ts +2 -0
- package/src/components/workload/WorkloadView.tsx +24 -3
- package/src/theme/tailwind-theme.css +1 -0
- package/src/theme/variables.css +1 -0
- package/src/types/gitops-insights.ts +69 -1
- package/src/types/gitops.ts +3 -3
- package/src/utils/application-history.test.ts +538 -0
- package/src/utils/application-history.ts +257 -0
- package/src/utils/applications.test.ts +34 -0
- package/src/utils/applications.ts +25 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/resource-hierarchy.test.ts +35 -1
- package/src/utils/resource-hierarchy.ts +20 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skyhook-io/k8s-ui",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.12",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/skyhook-io/radar",
|
|
@@ -92,15 +92,15 @@
|
|
|
92
92
|
"@xterm/addon-fit": "^0.11.0",
|
|
93
93
|
"@xterm/addon-web-links": "^0.12.0",
|
|
94
94
|
"@xterm/xterm": "^6.0.0",
|
|
95
|
-
"@xyflow/react": "^12.
|
|
95
|
+
"@xyflow/react": "^12.11.2",
|
|
96
96
|
"clsx": "^2.1.1",
|
|
97
97
|
"diff": "^9.0.0",
|
|
98
98
|
"elkjs": "^0.11.1",
|
|
99
|
-
"lucide-react": "^1.
|
|
99
|
+
"lucide-react": "^1.24.0",
|
|
100
100
|
"react": "^19.2.7",
|
|
101
101
|
"react-dom": "^19.2.7",
|
|
102
102
|
"typescript": "^6.0.2",
|
|
103
|
-
"vitest": "^4.1.
|
|
103
|
+
"vitest": "^4.1.10",
|
|
104
104
|
"yaml": "^2.9.0"
|
|
105
105
|
}
|
|
106
106
|
}
|
|
@@ -148,6 +148,33 @@ describe("ApplicationDetail shell", () => {
|
|
|
148
148
|
expect(html).not.toContain('Application identity')
|
|
149
149
|
})
|
|
150
150
|
|
|
151
|
+
it("renders the optional application cost view only when the host selects it", () => {
|
|
152
|
+
const withCostTab = renderDetail({
|
|
153
|
+
selectedView: "overview",
|
|
154
|
+
onSelectView: () => {},
|
|
155
|
+
selectedWorkloadKey: null,
|
|
156
|
+
onSelectWorkload: () => {},
|
|
157
|
+
renderCostView: () => <div>Application cost body</div>,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
expect(withCostTab).toContain("Cost");
|
|
161
|
+
expect(withCostTab).not.toContain("Application cost body");
|
|
162
|
+
|
|
163
|
+
const selectedCost = renderDetail({
|
|
164
|
+
selectedView: "overview",
|
|
165
|
+
onSelectView: () => {},
|
|
166
|
+
selectedWorkloadKey: null,
|
|
167
|
+
onSelectWorkload: () => {},
|
|
168
|
+
renderCostView: () => <div>Application cost body</div>,
|
|
169
|
+
costViewSelected: true,
|
|
170
|
+
onSelectCostView: () => {},
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
expect(selectedCost).toContain("Cost");
|
|
174
|
+
expect(selectedCost).toContain("Application cost body");
|
|
175
|
+
expect(selectedCost).not.toContain("Source & provenance");
|
|
176
|
+
});
|
|
177
|
+
|
|
151
178
|
it("does not render a workload selector for a single-workload app", () => {
|
|
152
179
|
const singleApp: AppRow = {
|
|
153
180
|
...app,
|
|
@@ -180,20 +207,112 @@ describe("ApplicationDetail shell", () => {
|
|
|
180
207
|
expect(html).not.toContain("Application views");
|
|
181
208
|
});
|
|
182
209
|
|
|
183
|
-
it("renders application
|
|
210
|
+
it("renders one filtered application chronology with workload and source actions", () => {
|
|
184
211
|
const html = renderDetail({
|
|
185
212
|
selectedView: "history",
|
|
186
213
|
onSelectView: () => {},
|
|
187
214
|
selectedWorkloadKey: null,
|
|
188
215
|
onSelectWorkload: () => {},
|
|
216
|
+
historyMode: 'local',
|
|
217
|
+
historyRange: 'all',
|
|
218
|
+
historyRangeOptions: [{ value: 'all', label: 'All observed' }],
|
|
219
|
+
onOpenTimeline: () => {},
|
|
220
|
+
historyItems: [
|
|
221
|
+
{
|
|
222
|
+
id: 'source-sync',
|
|
223
|
+
category: 'deployment',
|
|
224
|
+
title: 'Argo CD sync',
|
|
225
|
+
timestamp: '2026-07-13T10:00:00.000Z',
|
|
226
|
+
sourceRef: { type: 'gitops', tool: 'argocd', kind: 'Application', namespace: 'argocd', name: 'checkout' },
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
id: 'runtime-change',
|
|
230
|
+
category: 'change',
|
|
231
|
+
title: 'Deployment updated',
|
|
232
|
+
timestamp: '2026-07-13T09:00:00.000Z',
|
|
233
|
+
resource: { kind: 'Deployment', namespace: 'prod', name: 'checkout-api' },
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
id: 'problem',
|
|
237
|
+
category: 'problem',
|
|
238
|
+
title: 'BackOff',
|
|
239
|
+
timestamp: '2026-07-13T08:00:00.000Z',
|
|
240
|
+
resource: { kind: 'Pod', namespace: 'prod', name: 'checkout-api-abc12' },
|
|
241
|
+
},
|
|
242
|
+
],
|
|
243
|
+
onOpenSource: () => {},
|
|
189
244
|
});
|
|
190
245
|
|
|
191
|
-
expect(html).toContain("
|
|
192
|
-
expect(html).toContain("
|
|
193
|
-
expect(html).toContain("
|
|
194
|
-
expect(html).toContain("
|
|
246
|
+
expect(html).toContain("Application history");
|
|
247
|
+
expect(html).toContain("Deployments");
|
|
248
|
+
expect(html).toContain("Changes");
|
|
249
|
+
expect(html).toContain("Problems");
|
|
250
|
+
expect(html).toContain("Open full Timeline");
|
|
251
|
+
expect(html).toContain("Deployment");
|
|
252
|
+
expect(html).toContain("prod");
|
|
253
|
+
expect(html).toContain("checkout-api");
|
|
254
|
+
expect(html).toContain("View Argo CD application");
|
|
255
|
+
expect(html).toContain("events retained by this Radar instance");
|
|
256
|
+
expect(html).not.toContain("Current incidents");
|
|
195
257
|
});
|
|
196
258
|
|
|
259
|
+
it('reports retained event limits separately from recording gaps', () => {
|
|
260
|
+
const html = renderDetail({
|
|
261
|
+
selectedView: 'history',
|
|
262
|
+
onSelectView: () => {},
|
|
263
|
+
selectedWorkloadKey: null,
|
|
264
|
+
onSelectWorkload: () => {},
|
|
265
|
+
historyMode: 'retained',
|
|
266
|
+
historyRange: '7d',
|
|
267
|
+
historyRangeOptions: [{ value: '7d', label: '7 days' }],
|
|
268
|
+
historyRuntimeLimited: true,
|
|
269
|
+
historyItems: [{
|
|
270
|
+
id: 'runtime-change',
|
|
271
|
+
category: 'change',
|
|
272
|
+
title: 'Deployment updated',
|
|
273
|
+
timestamp: '2026-07-13T09:00:00.000Z',
|
|
274
|
+
}],
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
expect(html).toContain('Showing the 10,000 most recent events in these namespaces')
|
|
278
|
+
expect(html).not.toContain('Recording coverage is incomplete')
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
it('shows a single honest error state when runtime history fails without source history', () => {
|
|
282
|
+
const html = renderDetail({
|
|
283
|
+
selectedView: 'history',
|
|
284
|
+
onSelectView: () => {},
|
|
285
|
+
selectedWorkloadKey: null,
|
|
286
|
+
onSelectWorkload: () => {},
|
|
287
|
+
historyRuntimeError: true,
|
|
288
|
+
historyItems: [],
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
expect(html).toContain('Application changes could not be loaded.')
|
|
292
|
+
expect(html).not.toContain('Deployment-source history is still shown.')
|
|
293
|
+
expect(html).not.toContain('No application history in this range.')
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
it('marks retained runtime rows as stale when a refresh fails', () => {
|
|
297
|
+
const html = renderDetail({
|
|
298
|
+
selectedView: 'history',
|
|
299
|
+
onSelectView: () => {},
|
|
300
|
+
selectedWorkloadKey: null,
|
|
301
|
+
onSelectWorkload: () => {},
|
|
302
|
+
historyRuntimeError: true,
|
|
303
|
+
historyItems: [{
|
|
304
|
+
id: 'runtime-change',
|
|
305
|
+
category: 'change',
|
|
306
|
+
title: 'Deployment updated',
|
|
307
|
+
timestamp: '2026-07-13T09:00:00.000Z',
|
|
308
|
+
}],
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
expect(html).toContain('Application changes could not be refreshed.')
|
|
312
|
+
expect(html).toContain('Previously loaded changes may be stale.')
|
|
313
|
+
expect(html).toContain('Deployment updated')
|
|
314
|
+
})
|
|
315
|
+
|
|
197
316
|
it("previews the latest retained deployment change in Overview", () => {
|
|
198
317
|
const healthyApp: AppRow = { ...app, events: [] };
|
|
199
318
|
const history: AppHistory = {
|
|
@@ -429,7 +548,7 @@ describe("ApplicationDetail shell", () => {
|
|
|
429
548
|
expect(html).not.toContain('needs attention')
|
|
430
549
|
})
|
|
431
550
|
|
|
432
|
-
it("
|
|
551
|
+
it("uses the resource namespace when linking a history item to a workload", () => {
|
|
433
552
|
const ambiguousApp: AppRow = {
|
|
434
553
|
...app,
|
|
435
554
|
workloads: [
|
|
@@ -453,10 +572,19 @@ describe("ApplicationDetail shell", () => {
|
|
|
453
572
|
onSelectView: () => {},
|
|
454
573
|
selectedWorkloadKey: null,
|
|
455
574
|
onSelectWorkload: () => {},
|
|
575
|
+
historyItems: [{
|
|
576
|
+
id: 'prod-change',
|
|
577
|
+
category: 'change',
|
|
578
|
+
title: 'Deployment updated',
|
|
579
|
+
timestamp: '2026-07-13T09:00:00.000Z',
|
|
580
|
+
resource: { kind: 'Deployment', namespace: 'prod', name: 'checkout-api' },
|
|
581
|
+
}],
|
|
456
582
|
});
|
|
457
583
|
|
|
458
|
-
expect(html).toContain("Deployment
|
|
459
|
-
expect(html).
|
|
584
|
+
expect(html).toContain("Deployment");
|
|
585
|
+
expect(html).toContain("prod");
|
|
586
|
+
expect(html).toContain("checkout-api");
|
|
587
|
+
expect(html).not.toContain("canary/checkout-api");
|
|
460
588
|
});
|
|
461
589
|
|
|
462
590
|
it("shows batch activity and injected operational issues on the application overview", () => {
|