@skyhook-io/k8s-ui 1.16.3 → 1.17.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/README.md +41 -0
- package/package.json +3 -3
- package/src/components/applications/ApplicationDetail.test.tsx +15 -0
- package/src/components/applications/ApplicationDetail.tsx +17 -15
- package/src/components/charts/AreaChart.interaction.test.tsx +118 -0
- package/src/components/charts/AreaChart.test.tsx +25 -0
- package/src/components/charts/AreaChart.tsx +141 -12
- package/src/components/charts/index.ts +1 -0
- package/src/components/checks/ChecksView.tsx +18 -1
- package/src/components/checks/types.ts +2 -13
- package/src/components/cnpg/CNPGBackupSummary.tsx +57 -9
- package/src/components/cnpg/CNPGClusterHASection.test.tsx +90 -0
- package/src/components/cnpg/CNPGClusterHASection.tsx +331 -0
- package/src/components/cnpg/CNPGClusterSummary.test.tsx +275 -0
- package/src/components/cnpg/CNPGClusterSummary.tsx +310 -96
- package/src/components/cnpg/CNPGConnectSection.test.tsx +64 -0
- package/src/components/cnpg/CNPGConnectSection.tsx +178 -0
- package/src/components/cnpg/CNPGDeclarativeSummary.tsx +157 -26
- package/src/components/cnpg/CNPGImageCatalogSummary.tsx +7 -4
- package/src/components/cnpg/CNPGLogicalPath.test.tsx +22 -0
- package/src/components/cnpg/CNPGLogicalPath.tsx +150 -0
- package/src/components/cnpg/CNPGObjectStoreSummary.tsx +9 -6
- package/src/components/cnpg/CNPGObjectSummary.test.tsx +193 -2
- package/src/components/cnpg/CNPGPoolerScheduling.test.tsx +36 -0
- package/src/components/cnpg/CNPGPoolerSummary.tsx +241 -14
- package/src/components/cnpg/CNPGSharedSummary.tsx +15 -8
- package/src/components/cnpg/CNPGWALArchivingFact.test.tsx +39 -0
- package/src/components/cnpg/backupRuns.test.ts +17 -0
- package/src/components/cnpg/backupRuns.ts +19 -0
- package/src/components/cnpg/connect.test.ts +124 -0
- package/src/components/cnpg/connect.ts +155 -0
- package/src/components/cnpg/databaseRole.test.ts +38 -0
- package/src/components/cnpg/databaseRole.ts +80 -0
- package/src/components/cnpg/ha.test.ts +446 -0
- package/src/components/cnpg/ha.ts +621 -0
- package/src/components/cnpg/index.ts +18 -0
- package/src/components/cnpg/logicalReplication.test.ts +121 -0
- package/src/components/cnpg/logicalReplication.ts +252 -0
- package/src/components/cnpg/pooler.test.ts +84 -0
- package/src/components/cnpg/pooler.ts +225 -0
- package/src/components/cnpg/primitives.tsx +21 -117
- package/src/components/cnpg/problems.ts +12 -0
- package/src/components/cnpg/relations.test.ts +63 -13
- package/src/components/cnpg/relations.ts +61 -52
- package/src/components/cnpg/schedule.ts +35 -0
- package/src/components/cnpg/workspace-disk.test.ts +97 -0
- package/src/components/cnpg/workspace-fleet-metrics.test.ts +250 -0
- package/src/components/cnpg/workspace-problems.test.ts +175 -0
- package/src/components/cnpg/workspace.test.ts +380 -9
- package/src/components/cnpg/workspace.ts +1137 -136
- package/src/components/dock/DockContext.test.tsx +32 -0
- package/src/components/dock/DockContext.tsx +18 -4
- package/src/components/dock/LocalTerminalTab.test.tsx +40 -0
- package/src/components/dock/LocalTerminalTab.tsx +4 -3
- package/src/components/dock/TerminalTab.tsx +20 -8
- package/src/components/facts/certainty.tsx +36 -0
- package/src/components/facts/facts.test.tsx +24 -0
- package/src/components/facts/facts.tsx +62 -0
- package/src/components/facts/index.ts +6 -0
- package/src/components/facts/managed-by.test.tsx +17 -0
- package/src/components/facts/managed-by.tsx +36 -0
- package/src/components/facts/public-exports.test.tsx +35 -0
- package/src/components/gitops/GitOpsGraphFilterRail.tsx +6 -2
- package/src/components/gitops/GitOpsHealthSourceNotice.test.tsx +38 -0
- package/src/components/gitops/GitOpsHealthSourceNotice.tsx +13 -3
- package/src/components/gitops/GitOpsTableView.tsx +9 -24
- package/src/components/gitops/detail-helpers.ts +1 -1
- package/src/components/gitops/insights/ArgoResourceDiff.test.tsx +115 -0
- package/src/components/gitops/insights/ArgoResourceDiff.tsx +22 -5
- package/src/components/gitops/insights/DriftPanel.tsx +62 -0
- package/src/components/gitops/insights/GitOpsInsightViews.tsx +29 -83
- package/src/components/gitops/tree/GitOpsTreeGraph.test.ts +26 -1
- package/src/components/gitops/tree/GitOpsTreeGraph.tsx +40 -60
- package/src/components/gitops/tree/layout.test.ts +111 -0
- package/src/components/gitops/tree/layout.ts +128 -0
- package/src/components/gitops/tree/tree-helpers.test.ts +17 -0
- package/src/components/gitops/tree/tree-helpers.ts +7 -1
- package/src/components/issues/ConditionalCleanup.test.tsx +82 -0
- package/src/components/issues/IssuesView.tsx +40 -5
- package/src/components/issues/ResourceIssuesSection.test.tsx +28 -0
- package/src/components/issues/ResourceIssuesSection.tsx +3 -0
- package/src/components/issues/index.ts +3 -1
- package/src/components/issues/issue-timing.ts +14 -3
- package/src/components/issues/issues.test.ts +50 -2
- package/src/components/issues/severity.ts +21 -0
- package/src/components/issues/types.ts +23 -0
- package/src/components/logs/LogCore.theme.test.tsx +81 -3
- package/src/components/logs/LogCore.tsx +25 -17
- package/src/components/logs/LogToolbarSelects.tsx +3 -1
- package/src/components/logs/LogsViewer.test.tsx +291 -0
- package/src/components/logs/LogsViewer.tsx +72 -11
- package/src/components/logs/StructuredLogLine.test.tsx +76 -0
- package/src/components/logs/StructuredLogLine.tsx +22 -30
- package/src/components/logs/WorkloadLogsViewer.notice.test.tsx +59 -0
- package/src/components/logs/WorkloadLogsViewer.test.tsx +65 -0
- package/src/components/logs/WorkloadLogsViewer.tsx +44 -10
- package/src/components/logs/useLogBuffer.test.ts +8 -0
- package/src/components/logs/useLogStream.ts +28 -1
- package/src/components/problems/index.ts +1 -0
- package/src/components/problems/problems.test.tsx +63 -0
- package/src/components/problems/problems.tsx +165 -0
- package/src/components/resources/ActiveFilterBar.test.tsx +78 -0
- package/src/components/resources/ActiveFilterBar.tsx +86 -0
- package/src/components/resources/ResourcesSidebar.keyboard.test.tsx +42 -0
- package/src/components/resources/ResourcesSidebar.test.tsx +36 -2
- package/src/components/resources/ResourcesSidebar.tsx +92 -41
- package/src/components/resources/ResourcesView.kind-filter-memory.test.ts +52 -0
- package/src/components/resources/ResourcesView.kind-view.test.tsx +149 -0
- package/src/components/resources/ResourcesView.per-container.test.ts +56 -1
- package/src/components/resources/ResourcesView.tsx +309 -117
- package/src/components/resources/curated-column-ownership.test.ts +3 -3
- package/src/components/resources/renderers/AnalysisRunRenderer.tsx +3 -3
- package/src/components/resources/renderers/ArgoApplicationRenderer.tsx +6 -5
- package/src/components/resources/renderers/AutoscalingReferences.test.tsx +286 -0
- package/src/components/resources/renderers/CAPIClusterRenderer.tsx +5 -4
- package/src/components/resources/renderers/CAPIExactReferenceNavigation.test.tsx +27 -0
- package/src/components/resources/renderers/CAPIKubeadmControlPlaneRenderer.tsx +2 -2
- package/src/components/resources/renderers/CAPIMachineDeploymentRenderer.tsx +2 -2
- package/src/components/resources/renderers/CAPIMachinePoolRenderer.tsx +2 -2
- package/src/components/resources/renderers/CAPIMachineRenderer.tsx +2 -2
- package/src/components/resources/renderers/CAPIMachineSetRenderer.tsx +2 -2
- package/src/components/resources/renderers/CNPGBackupRenderer.test.tsx +23 -0
- package/src/components/resources/renderers/CNPGBackupRenderer.tsx +8 -19
- package/src/components/resources/renderers/CNPGClusterRenderer.tsx +7 -8
- package/src/components/resources/renderers/CNPGDeclarativeRenderer.tsx +25 -0
- package/src/components/resources/renderers/CNPGScheduledBackupRenderer.test.tsx +32 -0
- package/src/components/resources/renderers/CNPGScheduledBackupRenderer.tsx +9 -17
- package/src/components/resources/renderers/CNPGShared.tsx +2 -2
- package/src/components/resources/renderers/ClusterComplianceReportRenderer.tsx +2 -2
- package/src/components/resources/renderers/CompositeRenderer.navigation.test.tsx +35 -0
- package/src/components/resources/renderers/CompositeRenderer.tsx +3 -3
- package/src/components/resources/renderers/CompositionRenderer.tsx +3 -3
- package/src/components/resources/renderers/ConfigAuditReportRenderer.tsx +2 -2
- package/src/components/resources/renderers/ContourExactReferenceNavigation.test.tsx +34 -0
- package/src/components/resources/renderers/ContourHTTPProxyRenderer.tsx +11 -10
- package/src/components/resources/renderers/CronJobRenderer.tsx +6 -4
- package/src/components/resources/renderers/CronWorkflowRenderer.tsx +3 -2
- package/src/components/resources/renderers/EndpointSliceRenderer.test.tsx +62 -0
- package/src/components/resources/renderers/EndpointSliceRenderer.tsx +15 -14
- package/src/components/resources/renderers/EventRenderer.tsx +3 -3
- package/src/components/resources/renderers/ExperimentRenderer.tsx +2 -2
- package/src/components/resources/renderers/ExposedSecretReportRenderer.tsx +2 -2
- package/src/components/resources/renderers/ExternalSecretRenderer.tsx +2 -2
- package/src/components/resources/renderers/FluxHelmReleaseRenderer.tsx +4 -4
- package/src/components/resources/renderers/GRPCRouteRenderer.tsx +11 -24
- package/src/components/resources/renderers/GatewayRouteReferences.test.tsx +63 -0
- package/src/components/resources/renderers/GitRepositoryRenderer.tsx +3 -3
- package/src/components/resources/renderers/HPARenderer.tsx +57 -17
- package/src/components/resources/renderers/HTTPRouteRenderer.tsx +12 -25
- package/src/components/resources/renderers/HelmRepositoryRenderer.tsx +3 -3
- package/src/components/resources/renderers/IngressClassReferences.test.tsx +52 -0
- package/src/components/resources/renderers/IngressClassRenderer.tsx +10 -3
- package/src/components/resources/renderers/IngressRenderer.defaultBackend.test.tsx +33 -0
- package/src/components/resources/renderers/IngressRenderer.tsx +36 -5
- package/src/components/resources/renderers/IstioDestinationRuleRenderer.tsx +9 -9
- package/src/components/resources/renderers/IstioExactReferenceNavigation.test.tsx +34 -0
- package/src/components/resources/renderers/IstioVirtualServiceRenderer.tsx +5 -8
- package/src/components/resources/renderers/KarpenterNodeClaimRenderer.tsx +2 -14
- package/src/components/resources/renderers/KedaCredentials.test.tsx +85 -0
- package/src/components/resources/renderers/KedaScaledObjectRenderer.tsx +15 -13
- package/src/components/resources/renderers/KedaTriggerAuthRenderer.tsx +6 -3
- package/src/components/resources/renderers/KnativeEventingRenderer.tsx +24 -31
- package/src/components/resources/renderers/KnativeExactReferenceNavigation.test.tsx +47 -0
- package/src/components/resources/renderers/KnativeFlowRenderer.tsx +6 -7
- package/src/components/resources/renderers/KnativeNetworkingRenderer.tsx +7 -9
- package/src/components/resources/renderers/KnativeReferenceLink.tsx +14 -0
- package/src/components/resources/renderers/KnativeReferenceLinks.test.tsx +60 -0
- package/src/components/resources/renderers/KnativeSourceRenderer.tsx +9 -11
- package/src/components/resources/renderers/KustomizationRenderer.tsx +2 -2
- package/src/components/resources/renderers/KyvernoGlobalContextRenderer.tsx +3 -2
- package/src/components/resources/renderers/KyvernoQueueRenderers.tsx +4 -3
- package/src/components/resources/renderers/LeaseRenderer.tsx +3 -15
- package/src/components/resources/renderers/ManagedResourceRenderer.tsx +2 -2
- package/src/components/resources/renderers/MetricsUnavailableNotice.tsx +3 -2
- package/src/components/resources/renderers/NamespaceRenderer.test.ts +69 -2
- package/src/components/resources/renderers/NamespaceRenderer.tsx +6 -1
- package/src/components/resources/renderers/NodeRenderer.test.tsx +81 -1
- package/src/components/resources/renderers/NodeRenderer.tsx +56 -15
- package/src/components/resources/renderers/OCIRepositoryRenderer.tsx +3 -3
- package/src/components/resources/renderers/PodClassReferences.test.tsx +42 -0
- package/src/components/resources/renderers/PodNomination.test.tsx +57 -0
- package/src/components/resources/renderers/PodRenderer.test.tsx +32 -0
- package/src/components/resources/renderers/PodRenderer.tsx +62 -36
- package/src/components/resources/renderers/RolloutRenderer.test.tsx +1 -1
- package/src/components/resources/renderers/RolloutRenderer.tsx +3 -2
- package/src/components/resources/renderers/SbomReportRenderer.tsx +2 -2
- package/src/components/resources/renderers/SecretRenderer.test.tsx +88 -0
- package/src/components/resources/renderers/SecretRenderer.tsx +34 -5
- package/src/components/resources/renderers/ServiceRenderer.test.tsx +43 -0
- package/src/components/resources/renderers/ServiceRenderer.tsx +11 -3
- package/src/components/resources/renderers/SimpleRouteRenderer.tsx +9 -22
- package/src/components/resources/renderers/VPARenderer.tsx +17 -11
- package/src/components/resources/renderers/VeleroBSLRenderer.tsx +5 -7
- package/src/components/resources/renderers/VeleroBackupRenderer.tsx +3 -3
- package/src/components/resources/renderers/VeleroBackupRepositoryRenderer.tsx +2 -2
- package/src/components/resources/renderers/VeleroRestoreRenderer.tsx +3 -3
- package/src/components/resources/renderers/VeleroScheduleRenderer.tsx +2 -2
- package/src/components/resources/renderers/VulnerabilityReportRenderer.tsx +2 -2
- package/src/components/resources/renderers/WorkflowRenderer.tsx +4 -3
- package/src/components/resources/renderers/kyverno-modern-cells.tsx +1 -1
- package/src/components/resources/renderers/rollout/ReplicaSetProgression.tsx +2 -2
- package/src/components/resources/resource-utils-capi.ts +1 -1
- package/src/components/resources/resource-utils-cnpg.test.ts +35 -10
- package/src/components/resources/resource-utils-cnpg.ts +51 -24
- package/src/components/resources/resource-utils-contour.test.ts +44 -0
- package/src/components/resources/resource-utils-contour.ts +16 -0
- package/src/components/resources/resource-utils-istio.ts +12 -8
- package/src/components/resources/resource-utils-keda.ts +1 -7
- package/src/components/resources/resource-utils-knative.ts +18 -0
- package/src/components/resources/resource-utils-kyverno.ts +1 -7
- package/src/components/resources/resource-utils-velero.ts +0 -12
- package/src/components/resources/resource-utils.ts +99 -39
- package/src/components/resources/rules-column-width.test.ts +1 -1
- package/src/components/resources/summarize-scheduler-message.test.ts +30 -0
- package/src/components/shared/ActionConfirmDialog.test.tsx +154 -0
- package/src/components/shared/ActionConfirmDialog.tsx +246 -0
- package/src/components/shared/CreateResourceDialog.test.tsx +330 -0
- package/src/components/shared/CreateResourceDialog.tsx +126 -80
- package/src/components/shared/DetailShell.test.tsx +80 -0
- package/src/components/shared/DetailShell.tsx +85 -10
- package/src/components/shared/DrainPlanDialog.tsx +1 -0
- package/src/components/shared/EditableYamlView.test.tsx +7 -0
- package/src/components/shared/EditableYamlView.tsx +1 -1
- package/src/components/shared/GitOpsWriteWarning.test.tsx +86 -0
- package/src/components/shared/GitOpsWriteWarning.tsx +135 -0
- package/src/components/shared/ResourceActionsBar.tsx +20 -24
- package/src/components/shared/ResourceRendererDispatch.tsx +13 -10
- package/src/components/shared/SetImageDialog.test.ts +75 -6
- package/src/components/shared/SetImageDialog.tsx +92 -84
- package/src/components/shared/index.ts +4 -1
- package/src/components/timeline/TimelineList.tsx +2 -15
- package/src/components/timeline/TimelineSwimlanes.tsx +3 -11
- package/src/components/timeline/timeline-filters.ts +1 -0
- package/src/components/topology/K8sResourceNode.test.ts +18 -1
- package/src/components/topology/K8sResourceNode.tsx +44 -2
- package/src/components/topology/TopologyFilterSidebar.tsx +1 -0
- package/src/components/topology/TopologyGraph.tsx +8 -74
- package/src/components/topology/TopologySearch.tsx +1 -0
- package/src/components/topology/internet-groups.test.ts +35 -0
- package/src/components/topology/internet-groups.ts +55 -0
- package/src/components/topology/layout.ts +1 -1
- package/src/components/ui/Badge.tsx +1 -0
- package/src/components/ui/FoldSection.tsx +68 -0
- package/src/components/ui/ForceDeleteConfirmDialog.test.tsx +62 -0
- package/src/components/ui/ForceDeleteConfirmDialog.tsx +24 -12
- package/src/components/ui/RefLink.tsx +20 -0
- package/src/components/ui/RowActionMenu.tsx +8 -3
- package/src/components/ui/ScheduleValue.test.tsx +5 -0
- package/src/components/ui/ScheduleValue.tsx +3 -2
- package/src/components/ui/crd-definition-navigation.test.tsx +160 -0
- package/src/components/ui/drawer-components.test.tsx +175 -1
- package/src/components/ui/drawer-components.tsx +103 -36
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/monacoEditorFeatures.ts +77 -0
- package/src/components/ui/monacoRuntime.ts +14 -19
- package/src/components/ui/status-tone.test.ts +10 -1
- package/src/components/ui/status-tone.tsx +29 -0
- package/src/components/workload/WorkloadView.deleted.test.tsx +101 -0
- package/src/components/workload/WorkloadView.deletedDialog.test.tsx +45 -0
- package/src/components/workload/WorkloadView.relationships.test.tsx +37 -0
- package/src/components/workload/WorkloadView.secretSave.test.tsx +62 -0
- package/src/components/workload/WorkloadView.spec.test.tsx +149 -0
- package/src/components/workload/WorkloadView.tsx +297 -104
- package/src/index.ts +14 -1
- package/src/monaco-deep.d.ts +19 -12
- package/src/theme/components.css +13 -0
- package/src/types/capacity.ts +21 -2
- package/src/types/core.ts +60 -2
- package/src/types/gitops-flux-status.test.ts +32 -1
- package/src/types/gitops-insights.ts +19 -2
- package/src/types/gitops-tree.ts +10 -0
- package/src/types/gitops.ts +26 -6
- package/src/utils/api-resources.ts +7 -0
- package/src/utils/application-history.ts +1 -0
- package/src/utils/cnpg-backup.test.ts +26 -0
- package/src/utils/cnpg-backup.ts +70 -0
- package/src/utils/format.test.ts +49 -2
- package/src/utils/format.ts +9 -1
- package/src/utils/gateway-references.test.ts +17 -0
- package/src/utils/gateway-references.ts +29 -0
- package/src/utils/gitops-owner.ts +3 -2
- package/src/utils/gitops-write-guard.test.ts +401 -0
- package/src/utils/gitops-write-guard.ts +509 -0
- package/src/utils/grant.test.ts +19 -0
- package/src/utils/grant.ts +35 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/ingress-class-references.ts +22 -0
- package/src/utils/k8s-errors.ts +7 -7
- package/src/utils/log-format.test.ts +41 -0
- package/src/utils/log-format.ts +71 -15
- package/src/utils/log-level.ts +12 -8
- package/src/utils/navigation.test.ts +70 -0
- package/src/utils/navigation.ts +91 -8
- package/src/utils/node-lifecycle.test.ts +36 -0
- package/src/utils/node-lifecycle.ts +77 -0
- package/src/utils/object-reference-navigation.test.ts +43 -0
- package/src/utils/resource-hierarchy.test.ts +69 -0
- package/src/utils/resource-hierarchy.ts +41 -7
- package/src/utils/resource-icons.ts +2 -0
- package/src/utils/resource-refs.test.ts +23 -0
- package/src/utils/resource-refs.ts +30 -0
- package/src/utils/skeleton-yaml.test.ts +21 -0
- package/src/utils/skeleton-yaml.ts +16 -0
- package/src/utils/url-path.test.ts +35 -0
- package/src/utils/url-path.ts +21 -0
- package/src/utils/validators.test.ts +4 -13
- package/src/utils/validators.ts +5 -19
- package/src/utils/view-transition.test.ts +35 -1
- package/src/utils/view-transition.ts +16 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { act } from 'react'
|
|
3
|
+
import { createRoot } from 'react-dom/client'
|
|
4
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
5
|
+
import { ResourcesView } from './ResourcesView'
|
|
6
|
+
import { KeyboardShortcutProvider } from '../../hooks/useKeyboardShortcuts'
|
|
7
|
+
import type { APIResource } from '../../types'
|
|
8
|
+
|
|
9
|
+
;(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true
|
|
10
|
+
window.matchMedia = vi.fn().mockReturnValue({ matches: false, addEventListener: vi.fn(), removeEventListener: vi.fn() })
|
|
11
|
+
Element.prototype.scrollIntoView = vi.fn()
|
|
12
|
+
const pods: APIResource = { group: '', version: 'v1', kind: 'Pod', name: 'pods', namespaced: true, isCrd: false, verbs: ['get', 'list'] }
|
|
13
|
+
const pod = { apiVersion: 'v1', kind: 'Pod', metadata: { name: 'example', namespace: 'test', uid: 'pod-id' }, spec: { containers: [{ name: 'app', image: 'example' }] }, status: { phase: 'Running' } }
|
|
14
|
+
let root: ReturnType<typeof createRoot>
|
|
15
|
+
let host: HTMLDivElement
|
|
16
|
+
|
|
17
|
+
afterEach(() => { act(() => root?.unmount()); host?.remove(); vi.restoreAllMocks(); localStorage.clear() })
|
|
18
|
+
|
|
19
|
+
describe('custom resource kind view', () => {
|
|
20
|
+
it('keeps sidebar navigation while disabling table keys and column settings, then restores the table on null', () => {
|
|
21
|
+
host = document.createElement('div'); document.body.append(host); root = createRoot(host)
|
|
22
|
+
const selected = vi.fn()
|
|
23
|
+
const storageRead = vi.spyOn(Storage.prototype, 'getItem')
|
|
24
|
+
const storageWrite = vi.spyOn(Storage.prototype, 'setItem')
|
|
25
|
+
const render = (custom: boolean | undefined) => act(() => root.render(<KeyboardShortcutProvider><ResourcesView
|
|
26
|
+
namespaces={['test']}
|
|
27
|
+
apiResources={[pods]}
|
|
28
|
+
resourceCounts={{ Pod: 1 }}
|
|
29
|
+
selectedKindQuery={{ isLoading: false, data: [pod], resourceName: 'pods', group: '' }}
|
|
30
|
+
locationPathname="/resources/pods"
|
|
31
|
+
locationSearch=""
|
|
32
|
+
onNavigate={() => {}}
|
|
33
|
+
onResourceClick={selected}
|
|
34
|
+
renderKindView={kind => custom === undefined ? false : custom ? <div data-testid="kind-view">Custom {kind.kind}</div> : null}
|
|
35
|
+
/></KeyboardShortcutProvider>))
|
|
36
|
+
render(true)
|
|
37
|
+
expect(host.querySelector('[data-testid="kind-view"]')?.textContent).toBe('Custom Pod')
|
|
38
|
+
expect(host.querySelectorAll('table')).toHaveLength(0)
|
|
39
|
+
expect(host.textContent).toContain('Workloads')
|
|
40
|
+
act(() => document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'j', bubbles: true })))
|
|
41
|
+
act(() => document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })))
|
|
42
|
+
expect(selected).not.toHaveBeenCalled()
|
|
43
|
+
expect(storageRead.mock.calls.some(([key]) => String(key).startsWith('radar-columns-'))).toBe(false)
|
|
44
|
+
expect(storageWrite.mock.calls.some(([key]) => String(key).startsWith('radar-columns-'))).toBe(false)
|
|
45
|
+
render(false)
|
|
46
|
+
expect(host.querySelector('[data-testid="kind-view"]')).toBeNull()
|
|
47
|
+
expect(host.querySelector('table')).not.toBeNull()
|
|
48
|
+
expect(storageRead.mock.calls.some(([key]) => key === 'radar-columns-pods')).toBe(true)
|
|
49
|
+
act(() => document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'j', bubbles: true })))
|
|
50
|
+
act(() => document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })))
|
|
51
|
+
expect(selected).toHaveBeenCalledWith(expect.objectContaining({ kind: 'pods', namespace: 'test', name: 'example' }))
|
|
52
|
+
render(undefined)
|
|
53
|
+
expect(host.querySelector('table')).not.toBeNull()
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('closes bulk dialogs when the same kind switches to a custom view and keeps the inspected resource', async () => {
|
|
58
|
+
host = document.createElement('div'); document.body.append(host); root = createRoot(host)
|
|
59
|
+
const selected = vi.fn()
|
|
60
|
+
const remove = vi.fn()
|
|
61
|
+
const render = (custom: boolean) => act(() => root.render(<KeyboardShortcutProvider><ResourcesView
|
|
62
|
+
namespaces={['test']}
|
|
63
|
+
apiResources={[pods]}
|
|
64
|
+
resourceCounts={{ Pod: 1 }}
|
|
65
|
+
selectedKindQuery={{ isLoading: false, data: [pod], resourceName: 'pods', group: '' }}
|
|
66
|
+
selectedResource={{ kind: 'pods', group: '', namespace: 'test', name: 'example' }}
|
|
67
|
+
locationPathname="/resources/pods"
|
|
68
|
+
locationSearch=""
|
|
69
|
+
onNavigate={() => {}}
|
|
70
|
+
onResourceClick={selected}
|
|
71
|
+
onBulkDelete={remove}
|
|
72
|
+
renderKindView={() => custom ? <div data-testid="custom">Custom</div> : null}
|
|
73
|
+
/></KeyboardShortcutProvider>))
|
|
74
|
+
render(false)
|
|
75
|
+
act(() => document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'b', bubbles: true })))
|
|
76
|
+
act(() => host.querySelector<HTMLInputElement>('input[title="Select all"]')!.click())
|
|
77
|
+
expect(host.textContent).toContain('1 selected')
|
|
78
|
+
act(() => [...host.querySelectorAll('button')].find(b => b.textContent?.trim() === 'Delete')!.click())
|
|
79
|
+
expect(document.querySelector('[role="dialog"]')?.textContent).toContain('Delete 1 Pod?')
|
|
80
|
+
render(true)
|
|
81
|
+
await act(async () => { await new Promise(resolve => setTimeout(resolve, 300)) })
|
|
82
|
+
expect(host.querySelector('[data-testid="custom"]')).not.toBeNull()
|
|
83
|
+
expect(document.querySelector('[role="dialog"]')).toBeNull()
|
|
84
|
+
render(false)
|
|
85
|
+
expect(host.textContent).not.toContain('1 selected')
|
|
86
|
+
expect(host.querySelector('input[title="Select all"]')).toBeNull()
|
|
87
|
+
expect(document.querySelector('[role="dialog"]')).toBeNull()
|
|
88
|
+
act(() => host.querySelector<SVGElement>('button .lucide-git-compare')!.closest<HTMLButtonElement>('button')!.click())
|
|
89
|
+
act(() => document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'j', bubbles: true })))
|
|
90
|
+
act(() => document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })))
|
|
91
|
+
expect(host.querySelector('[aria-label="Compare resources tray"]')?.textContent).toContain('example')
|
|
92
|
+
render(true)
|
|
93
|
+
render(false)
|
|
94
|
+
expect(host.querySelector('[aria-label="Compare resources tray"]')).toBeNull()
|
|
95
|
+
expect(remove).not.toHaveBeenCalled()
|
|
96
|
+
expect(selected).not.toHaveBeenCalled()
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('keeps sidebar kind shortcuts active while a custom view is shown', () => {
|
|
100
|
+
host = document.createElement('div'); document.body.append(host); root = createRoot(host)
|
|
101
|
+
const deployments: APIResource = { group: 'apps', version: 'v1', kind: 'Deployment', name: 'deployments', namespaced: true, isCrd: false, verbs: ['get', 'list'] }
|
|
102
|
+
act(() => root.render(<KeyboardShortcutProvider><ResourcesView
|
|
103
|
+
namespaces={['test']}
|
|
104
|
+
apiResources={[pods, deployments]}
|
|
105
|
+
resourceCounts={{ Pod: 1, Deployment: 1 }}
|
|
106
|
+
locationPathname="/resources/pods"
|
|
107
|
+
locationSearch=""
|
|
108
|
+
onNavigate={() => {}}
|
|
109
|
+
renderKindView={kind => <div data-testid="kind-view">Custom {kind.kind}</div>}
|
|
110
|
+
/></KeyboardShortcutProvider>))
|
|
111
|
+
expect(host.querySelector('[data-testid="kind-view"]')?.textContent).toBe('Custom Pod')
|
|
112
|
+
act(() => document.body.dispatchEvent(new KeyboardEvent('keydown', { key: ']', bubbles: true })))
|
|
113
|
+
expect(host.querySelector('[data-testid="kind-view"]')?.textContent).not.toBe('Custom Pod')
|
|
114
|
+
act(() => document.body.dispatchEvent(new KeyboardEvent('keydown', { key: '[', bubbles: true })))
|
|
115
|
+
expect(host.querySelector('[data-testid="kind-view"]')?.textContent).toBe('Custom Pod')
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('skips hidden-table sort and filter aggregation for a loaded list, then resumes them with the table', () => {
|
|
119
|
+
host = document.createElement('div'); document.body.append(host); root = createRoot(host)
|
|
120
|
+
const getSortValue = vi.fn((resource: typeof pod) => resource.metadata.name)
|
|
121
|
+
const getFilterValue = vi.fn((resource: typeof pod) => resource.metadata.name)
|
|
122
|
+
const extraColumns = [{ key: 'fixture-rank', label: 'Fixture rank', render: () => null, getSortValue, getFilterValue }]
|
|
123
|
+
const list = [pod, { ...pod, metadata: { ...pod.metadata, name: 'another', uid: 'another-id' } }]
|
|
124
|
+
localStorage.setItem('radar-sort-pods', JSON.stringify({ column: 'fixture-rank', direction: 'asc' }))
|
|
125
|
+
const render = (custom: boolean, data = list) => act(() => root.render(<KeyboardShortcutProvider><ResourcesView
|
|
126
|
+
namespaces={['test']}
|
|
127
|
+
apiResources={[pods]}
|
|
128
|
+
resourceCounts={{ Pod: data.length }}
|
|
129
|
+
selectedKindQuery={{ isLoading: false, data, resourceName: 'pods', group: '' }}
|
|
130
|
+
locationPathname="/resources/pods"
|
|
131
|
+
locationSearch=""
|
|
132
|
+
onNavigate={() => {}}
|
|
133
|
+
extraLeadingColumns={extraColumns}
|
|
134
|
+
renderKindView={() => custom ? <div data-testid="kind-view">Custom</div> : null}
|
|
135
|
+
/></KeyboardShortcutProvider>))
|
|
136
|
+
render(true)
|
|
137
|
+
expect(getSortValue).not.toHaveBeenCalled()
|
|
138
|
+
expect(getFilterValue).not.toHaveBeenCalled()
|
|
139
|
+
render(false)
|
|
140
|
+
expect(getSortValue).toHaveBeenCalled()
|
|
141
|
+
expect(getFilterValue).toHaveBeenCalled()
|
|
142
|
+
getSortValue.mockClear(); getFilterValue.mockClear()
|
|
143
|
+
render(true, [...list])
|
|
144
|
+
expect(getSortValue).not.toHaveBeenCalled()
|
|
145
|
+
expect(getFilterValue).not.toHaveBeenCalled()
|
|
146
|
+
render(false)
|
|
147
|
+
expect(getSortValue).toHaveBeenCalled()
|
|
148
|
+
expect(getFilterValue).toHaveBeenCalled()
|
|
149
|
+
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { renderToStaticMarkup } from 'react-dom/server'
|
|
1
2
|
import { describe, expect, it } from 'vitest'
|
|
2
3
|
import type { ContainerResourceMetrics } from '../../types'
|
|
3
|
-
import { podAggregate, readContainer } from './ResourcesView'
|
|
4
|
+
import { buildContainerResourceTooltip, podAggregate, readContainer } from './ResourcesView'
|
|
4
5
|
|
|
5
6
|
// Build a CPU-only container fixture; memory fields default to 0.
|
|
6
7
|
function cpu(name: string, usage: number, request: number, limit: number): ContainerResourceMetrics {
|
|
@@ -109,3 +110,57 @@ describe('podAggregate', () => {
|
|
|
109
110
|
expect(result.denom).toBe(384) // summed memory limit
|
|
110
111
|
})
|
|
111
112
|
})
|
|
113
|
+
|
|
114
|
+
describe('podAggregate with pod-level resources', () => {
|
|
115
|
+
it("treats a pod-level limit as the ceiling even when containers set none", () => {
|
|
116
|
+
const containers = [cpu('app', 300, 0, 0), cpu('sidecar', 100, 0, 0)]
|
|
117
|
+
const result = podAggregate(containers, 'cpu', { request: 500, limit: 1000 })
|
|
118
|
+
expect(result.mode).toBe('limit')
|
|
119
|
+
expect(result.denom).toBe(1000)
|
|
120
|
+
expect(result.markerPct).toBeCloseTo(50)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it("uses the pod-level limit over a partial container sum", () => {
|
|
124
|
+
const containers = [cpu('app', 300, 0, 0), cpu('sidecar', 100, 0, 200)]
|
|
125
|
+
const result = podAggregate(containers, 'cpu', { limit: 1000 })
|
|
126
|
+
expect(result.mode).toBe('limit')
|
|
127
|
+
expect(result.denom).toBe(1000)
|
|
128
|
+
expect(result.markerPct).toBeUndefined()
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it("uses the container limits when they are tighter than the pod limit", () => {
|
|
132
|
+
const single = podAggregate([cpu('app', 450, 100, 500)], 'cpu', { request: 800, limit: 1000 })
|
|
133
|
+
expect(single.mode).toBe('limit')
|
|
134
|
+
expect(single.denom).toBe(500)
|
|
135
|
+
const both = podAggregate([cpu('app', 200, 0, 300), cpu('sidecar', 50, 0, 300)], 'cpu', { limit: 1000 })
|
|
136
|
+
expect(both.denom).toBe(600)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it("uses a pod-level request as the yardstick when nothing is limited", () => {
|
|
140
|
+
const containers = [cpu('app', 300, 0, 0), cpu('sidecar', 100, 0, 0)]
|
|
141
|
+
const result = podAggregate(containers, 'cpu', { request: 800 })
|
|
142
|
+
expect(result.mode).toBe('request')
|
|
143
|
+
expect(result.denom).toBe(800)
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
describe('buildContainerResourceTooltip with a pod-level budget', () => {
|
|
148
|
+
const fmt = (n: number) => `${n}m`
|
|
149
|
+
const containers = [cpu('app', 300, 0, 0), cpu('sidecar', 100, 0, 0)]
|
|
150
|
+
|
|
151
|
+
it('shows the shared pod budget instead of calling covered containers unlimited', () => {
|
|
152
|
+
const html = renderToStaticMarkup(
|
|
153
|
+
buildContainerResourceTooltip('CPU', containers, 'cpu', fmt, undefined, { usage: 400, limit: 1000, request: 500 }),
|
|
154
|
+
)
|
|
155
|
+
expect(html).not.toContain('no limit')
|
|
156
|
+
expect(html).toContain('pod limit')
|
|
157
|
+
expect(html).toContain('Pod (shared)')
|
|
158
|
+
expect(html).toContain('400m · 40% · 1000m limit · req 500m')
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
it('keeps "no limit" when there is no pod-level budget', () => {
|
|
162
|
+
const html = renderToStaticMarkup(buildContainerResourceTooltip('CPU', containers, 'cpu', fmt))
|
|
163
|
+
expect(html).toContain('no limit')
|
|
164
|
+
expect(html).not.toContain('Pod (shared)')
|
|
165
|
+
})
|
|
166
|
+
})
|