@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
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
import { renderToString } from 'react-dom/server'
|
|
3
|
-
import { EventsSection, ProblemAlerts, OperationalIssuesShownContext, RelatedResourcesSection } from './drawer-components'
|
|
3
|
+
import { AlertBanner, EventsSection, ProblemAlerts, OperationalIssuesShownContext, RelatedResourcesSection, defaultConditionTone } from './drawer-components'
|
|
4
4
|
|
|
5
5
|
const problems = [
|
|
6
6
|
{ color: 'red' as const, message: 'Application is Degraded' },
|
|
7
7
|
{ color: 'yellow' as const, message: 'Application is OutOfSync' },
|
|
8
8
|
]
|
|
9
9
|
|
|
10
|
+
describe('GKE node condition polarity', () => {
|
|
11
|
+
it.each(['StoragePressureRootFileSystem', 'DPv2MigrationUnsupportedCNI', 'UnsupportedEBPFPrograms'])('%s is a problem only when True', type => {
|
|
12
|
+
expect(defaultConditionTone({ type, status: 'False' })).toBe('ok')
|
|
13
|
+
expect(defaultConditionTone({ type, status: 'True' })).toBe('fail')
|
|
14
|
+
expect(defaultConditionTone({ type, status: 'Unknown' })).toBe('unknown')
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
|
|
10
18
|
describe('ProblemAlerts', () => {
|
|
11
19
|
it('renders every problem', () => {
|
|
12
20
|
const html = renderToString(<ProblemAlerts problems={problems} />)
|
|
@@ -62,3 +70,169 @@ describe('Recent Events layout', () => {
|
|
|
62
70
|
expect(fullscreen).toContain('Reason23')
|
|
63
71
|
})
|
|
64
72
|
})
|
|
73
|
+
|
|
74
|
+
describe('dependency relationships', () => {
|
|
75
|
+
it('renders a dependency-only response with the existing navigation control', () => {
|
|
76
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ dependencies: [{ kind: 'Issuer', group: 'cert-manager.io', namespace: 'team', name: 'ca' }] }} onNavigate={() => {}} />)
|
|
77
|
+
expect(html).toContain('Depends On')
|
|
78
|
+
expect(html).toContain('ca')
|
|
79
|
+
expect(html).toContain('<button')
|
|
80
|
+
expect(html).not.toContain('Scale Target')
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('renders the reverse dependency without calling it an autoscaler', () => {
|
|
84
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ dependents: [{ kind: 'Certificate', group: 'cert-manager.io', namespace: 'team', name: 'tls' }] }} />)
|
|
85
|
+
expect(html).toContain('Required By')
|
|
86
|
+
expect(html).toContain('tls')
|
|
87
|
+
expect(html).not.toContain('Autoscaler')
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
describe('versioned dependency projections', () => {
|
|
92
|
+
const issuer = { kind: 'Issuer', group: 'cert-manager.io', namespace: 'team', name: 'ca' }
|
|
93
|
+
const certificate = { kind: 'Certificate', group: 'cert-manager.io', namespace: 'team', name: 'tls' }
|
|
94
|
+
|
|
95
|
+
it('presents mirrored configuration dependencies once under the specific labels', () => {
|
|
96
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ dependencies: [issuer], configRefs: [issuer], dependents: [certificate], consumers: [certificate] }} onNavigate={() => {}} />)
|
|
97
|
+
expect(html).toContain('Depends On')
|
|
98
|
+
expect(html).toContain('Required By')
|
|
99
|
+
expect(html).not.toContain('Configuration')
|
|
100
|
+
expect(html).not.toContain('Used By')
|
|
101
|
+
expect(html.match(/<button/g)).toHaveLength(3)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('preserves configuration and consumer groups when dependency fields are absent', () => {
|
|
105
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ configRefs: [issuer], consumers: [certificate] }} />)
|
|
106
|
+
expect(html).toContain('Configuration')
|
|
107
|
+
expect(html).toContain('Used By')
|
|
108
|
+
expect(html).not.toContain('Depends On')
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('retains navigation controls for identically named resources from distinct API groups', () => {
|
|
112
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ dependencies: [issuer, { ...issuer, group: 'other.example.com' }, issuer] }} onNavigate={() => {}} />)
|
|
113
|
+
expect(html.match(/<button/g)).toHaveLength(3)
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
describe('namespace deletion condition polarity', () => {
|
|
118
|
+
it.each([
|
|
119
|
+
'NamespaceDeletionDiscoveryFailure',
|
|
120
|
+
'NamespaceDeletionGroupVersionParsingFailure',
|
|
121
|
+
'NamespaceDeletionContentFailure',
|
|
122
|
+
'NamespaceContentRemaining',
|
|
123
|
+
'NamespaceFinalizersRemaining',
|
|
124
|
+
])('%s treats True as a blocker and False as cleared', (type) => {
|
|
125
|
+
expect(defaultConditionTone({ type, status: 'True' })).toBe('fail')
|
|
126
|
+
expect(defaultConditionTone({ type, status: 'False' })).toBe('ok')
|
|
127
|
+
expect(defaultConditionTone({ type, status: 'Unknown' })).toBe('unknown')
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
describe('monitors projection', () => {
|
|
132
|
+
it('renders Monitored By alone and deduplicates by API group', () => {
|
|
133
|
+
const ref = { kind: 'Widget', group: 'one.example', namespace: 'demo', name: 'shared' }
|
|
134
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ monitors: [ref, ref, { ...ref, group: 'two.example' }] }} onNavigate={() => {}} />)
|
|
135
|
+
expect(html).toContain('Related Resources')
|
|
136
|
+
expect(html).toContain('Monitored By')
|
|
137
|
+
expect(html.match(/<button/g)).toHaveLength(3)
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
describe('monitorTargets projection', () => {
|
|
143
|
+
it('renders Monitors alone and deduplicates by API group', () => {
|
|
144
|
+
const ref = { kind: 'Widget', group: 'one.example', namespace: 'demo', name: 'shared' }
|
|
145
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ monitorTargets: [ref, ref, { ...ref, group: 'two.example' }] }} onNavigate={() => {}} />)
|
|
146
|
+
expect(html).toContain('Related Resources')
|
|
147
|
+
expect(html).toContain('Monitors')
|
|
148
|
+
expect(html.match(/<button/g)).toHaveLength(3)
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
describe('backends projection', () => {
|
|
154
|
+
it('renders Routes To alone and deduplicates by API group', () => {
|
|
155
|
+
const ref = { kind: 'Widget', group: 'one.example', namespace: 'demo', name: 'shared' }
|
|
156
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ backends: [ref, ref, { ...ref, group: 'two.example' }] }} onNavigate={() => {}} />)
|
|
157
|
+
expect(html).toContain('Related Resources')
|
|
158
|
+
expect(html).toContain('Routes To')
|
|
159
|
+
expect(html.match(/<button/g)).toHaveLength(3)
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
describe('routedFrom projection', () => {
|
|
165
|
+
it('renders Routed From alone and deduplicates by API group', () => {
|
|
166
|
+
const ref = { kind: 'Widget', group: 'one.example', namespace: 'demo', name: 'shared' }
|
|
167
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ routedFrom: [ref, ref, { ...ref, group: 'two.example' }] }} onNavigate={() => {}} />)
|
|
168
|
+
expect(html).toContain('Related Resources')
|
|
169
|
+
expect(html).toContain('Routed From')
|
|
170
|
+
expect(html.match(/<button/g)).toHaveLength(3)
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
describe('protects projection', () => {
|
|
176
|
+
it('renders Selects alone and deduplicates by API group', () => {
|
|
177
|
+
const ref = { kind: 'Widget', group: 'one.example', namespace: 'demo', name: 'shared' }
|
|
178
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ protects: [ref, ref, { ...ref, group: 'two.example' }] }} onNavigate={() => {}} />)
|
|
179
|
+
expect(html).toContain('Related Resources')
|
|
180
|
+
expect(html).toContain('Selects')
|
|
181
|
+
expect(html.match(/<button/g)).toHaveLength(3)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
describe('healthChecks projection', () => {
|
|
187
|
+
it('renders Health Checks alone and deduplicates by API group', () => {
|
|
188
|
+
const ref = { kind: 'Widget', group: 'one.example', namespace: 'demo', name: 'shared' }
|
|
189
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ healthChecks: [ref, ref, { ...ref, group: 'two.example' }] }} onNavigate={() => {}} />)
|
|
190
|
+
expect(html).toContain('Related Resources')
|
|
191
|
+
expect(html).toContain('Health Checks')
|
|
192
|
+
expect(html.match(/<button/g)).toHaveLength(3)
|
|
193
|
+
})
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
describe('stagedPolicies projection', () => {
|
|
198
|
+
it('renders Staged Policies alone and deduplicates by API group', () => {
|
|
199
|
+
const ref = { kind: 'Widget', group: 'one.example', namespace: 'demo', name: 'shared' }
|
|
200
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ stagedPolicies: [ref, ref, { ...ref, group: 'two.example' }] }} onNavigate={() => {}} />)
|
|
201
|
+
expect(html).toContain('Related Resources')
|
|
202
|
+
expect(html).toContain('Staged Policies')
|
|
203
|
+
expect(html.match(/<button/g)).toHaveLength(3)
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
describe('routing version skew', () => {
|
|
209
|
+
it('keeps older Services, Gateways, Routes and Pods fields visible', () => {
|
|
210
|
+
const html = renderToString(<RelatedResourcesSection relationships={{ services: [{kind: 'Service', namespace: 'demo', name: 'web'}], gateways: [{kind: 'HTTPRoute', group: 'gateway.networking.k8s.io', namespace: 'demo', name: 'old-route'}], routes: [{kind: 'IngressRoute', group: 'traefik.io', namespace: 'demo', name: 'route'}], pods: [{kind: 'Deployment', group: 'apps', namespace: 'demo', name: 'old-target'}] }} />)
|
|
211
|
+
for (const label of ['Services', 'Gateways', 'Routes', 'Pods', 'old-route', 'old-target']) expect(html).toContain(label)
|
|
212
|
+
})
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
describe('related resource chips', () => {
|
|
216
|
+
it('tells a Knative Service apart from a core Service', () => {
|
|
217
|
+
const html = renderToString(<RelatedResourcesSection relationships={{
|
|
218
|
+
services: [{ kind: 'Service', namespace: 'team', name: 'web-private' }],
|
|
219
|
+
routedFrom: [{ kind: 'Service', group: 'serving.knative.dev', namespace: 'team', name: 'web' }],
|
|
220
|
+
}} onNavigate={() => {}} />)
|
|
221
|
+
expect(html).toContain('>svc<!-- -->/</span>web-private<')
|
|
222
|
+
expect(html).toContain('>ksvc<!-- -->/</span>web<')
|
|
223
|
+
})
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
describe('AlertBanner optional actions', () => {
|
|
228
|
+
it('retains the title-only default without introducing a layout wrapper', () => {
|
|
229
|
+
const html = renderToString(<AlertBanner variant="info" title="Paused" />)
|
|
230
|
+
expect(html).toMatch(/<div class="text-sm font-medium [^"]*">Paused<\/div>/)
|
|
231
|
+
expect(html).not.toContain('justify-between'); expect(html).not.toContain('flex-1')
|
|
232
|
+
})
|
|
233
|
+
it.each([undefined, 'Check connection'])('places the optional action next to the title, retaining the body (%s)', message => {
|
|
234
|
+
const html = renderToString(<AlertBanner variant="warning" title="Metrics unavailable" message={message} action={<button>Open settings</button>} />)
|
|
235
|
+
expect(html).toContain('Metrics unavailable'); expect(html).toContain('<button>Open settings</button>')
|
|
236
|
+
expect(html).toContain('flex-wrap'); if (message) expect(html).toContain(message)
|
|
237
|
+
})
|
|
238
|
+
})
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { dedupeResourceRefs, omitResourceRefs } from '../../utils/resource-refs'
|
|
2
|
+
import { customResourceDefinitionRef, getCRDDefinitionsSnapshot, subscribeCRDDefinitions } from '../../utils/navigation'
|
|
1
3
|
import { Disclosure } from './Disclosure'
|
|
2
|
-
import { createContext, useContext, useState } from 'react'
|
|
4
|
+
import { createContext, useContext, useState, useSyncExternalStore } from 'react'
|
|
3
5
|
import { Copy, Check, Tag, AlertTriangle, CheckCircle, ExternalLink, Layers, X, Minus } from 'lucide-react'
|
|
4
6
|
import { clsx } from 'clsx'
|
|
5
|
-
import {
|
|
7
|
+
import { formatDuration, formatResources } from '../resources/resource-utils'
|
|
6
8
|
import { getEffectiveResources } from '../../utils/extended-resources'
|
|
7
9
|
import { Tooltip } from './Tooltip'
|
|
8
10
|
import { getKindColorClass } from '../ui/Badge'
|
|
@@ -206,6 +208,12 @@ const NEGATIVE_POLARITY_TYPES = new Set([
|
|
|
206
208
|
'NetworkUnavailable',
|
|
207
209
|
// Core K8s — Pod
|
|
208
210
|
'DisruptionTarget',
|
|
211
|
+
// Core K8s — Namespace
|
|
212
|
+
'NamespaceDeletionDiscoveryFailure',
|
|
213
|
+
'NamespaceDeletionGroupVersionParsingFailure',
|
|
214
|
+
'NamespaceDeletionContentFailure',
|
|
215
|
+
'NamespaceContentRemaining',
|
|
216
|
+
'NamespaceFinalizersRemaining',
|
|
209
217
|
// Core K8s — workloads
|
|
210
218
|
'ReplicaFailure',
|
|
211
219
|
// NPD — upstream default configs
|
|
@@ -220,6 +228,9 @@ const NEGATIVE_POLARITY_TYPES = new Set([
|
|
|
220
228
|
'ReadOnlyRootFileSystem',
|
|
221
229
|
'ResourceExhausted',
|
|
222
230
|
'Swap',
|
|
231
|
+
'StoragePressureRootFileSystem',
|
|
232
|
+
'DPv2MigrationUnsupportedCNI',
|
|
233
|
+
'UnsupportedEBPFPrograms',
|
|
223
234
|
// NPD — AKS extensions (learn.microsoft.com/azure/aks/node-problem-detector)
|
|
224
235
|
'FilesystemCorruptionProblem',
|
|
225
236
|
'KubeletProblem',
|
|
@@ -382,6 +393,8 @@ export function ConditionsSection({
|
|
|
382
393
|
// ============================================================================
|
|
383
394
|
|
|
384
395
|
const ALERT_COLORS = {
|
|
396
|
+
alert: { bg: 'status-alert', border: '', title: '', message: '', list: '', bullet: '' },
|
|
397
|
+
unknown: { bg: 'status-unknown', border: '', title: '', message: '', list: '', bullet: '' },
|
|
385
398
|
error: { bg: 'bg-red-50 dark:bg-red-950/30', border: 'border-red-200 dark:border-red-800/30', title: 'text-red-700 dark:text-red-300', message: 'text-red-600/80 dark:text-red-300/70', list: 'text-red-600 dark:text-red-400', bullet: 'text-red-400/60 dark:text-red-400/50' },
|
|
386
399
|
warning: { bg: 'bg-amber-50 dark:bg-amber-950/30', border: 'border-amber-200 dark:border-amber-800/30', title: 'text-amber-700 dark:text-amber-300', message: 'text-amber-600/80 dark:text-amber-300/70', list: 'text-amber-600 dark:text-amber-400', bullet: 'text-amber-400/60 dark:text-amber-400/50' },
|
|
387
400
|
info: { bg: 'bg-sky-50 dark:bg-sky-950/30', border: 'border-sky-200 dark:border-sky-800/30', title: 'text-sky-700 dark:text-sky-300', message: 'text-sky-600/80 dark:text-sky-300/70', list: 'text-sky-600 dark:text-sky-400', bullet: 'text-sky-400/60 dark:text-sky-400/50' },
|
|
@@ -389,6 +402,8 @@ const ALERT_COLORS = {
|
|
|
389
402
|
} as const
|
|
390
403
|
|
|
391
404
|
const DEFAULT_ICONS: Record<string, React.ComponentType<{ className?: string }>> = {
|
|
405
|
+
alert: AlertTriangle,
|
|
406
|
+
unknown: AlertTriangle,
|
|
392
407
|
error: AlertTriangle,
|
|
393
408
|
warning: AlertTriangle,
|
|
394
409
|
info: AlertTriangle,
|
|
@@ -396,26 +411,37 @@ const DEFAULT_ICONS: Record<string, React.ComponentType<{ className?: string }>>
|
|
|
396
411
|
}
|
|
397
412
|
|
|
398
413
|
interface AlertBannerProps {
|
|
399
|
-
variant:
|
|
414
|
+
variant: keyof typeof ALERT_COLORS
|
|
400
415
|
icon?: React.ComponentType<{ className?: string }>
|
|
401
416
|
title: string
|
|
402
417
|
message?: React.ReactNode
|
|
403
418
|
items?: string[]
|
|
404
419
|
children?: React.ReactNode
|
|
420
|
+
/** A control at the end of the title line, e.g. a link to where the problem is handled. */
|
|
421
|
+
action?: React.ReactNode
|
|
422
|
+
/** Replaces the default bottom margin (`mb-4`). */
|
|
423
|
+
className?: string
|
|
405
424
|
}
|
|
406
425
|
|
|
407
|
-
export function AlertBanner({ variant, icon, title, message, items, children }: AlertBannerProps) {
|
|
426
|
+
export function AlertBanner({ variant, icon, title, message, items, children, action, className }: AlertBannerProps) {
|
|
408
427
|
const colors = ALERT_COLORS[variant]
|
|
409
428
|
const Icon = icon || DEFAULT_ICONS[variant]
|
|
410
429
|
const hasBody = message || items || children
|
|
411
430
|
|
|
412
431
|
return (
|
|
413
|
-
<div className={clsx('
|
|
432
|
+
<div className={clsx('p-3 border rounded-lg', className ?? 'mb-4', colors.bg, colors.border)}>
|
|
414
433
|
<div className={clsx('flex gap-2', hasBody ? 'items-start' : 'items-center')}>
|
|
415
434
|
<Icon className={clsx('w-4 h-4 shrink-0', colors.title, hasBody && 'mt-0.5')} />
|
|
416
435
|
{hasBody ? (
|
|
417
436
|
<div className="flex-1 min-w-0">
|
|
418
|
-
|
|
437
|
+
{action ? (
|
|
438
|
+
<div className={clsx('flex flex-wrap items-baseline justify-between gap-x-3 gap-y-1', items && 'mb-1')}>
|
|
439
|
+
<div className={clsx('min-w-0 text-sm font-medium', colors.title)}>{title}</div>
|
|
440
|
+
<div className="shrink-0">{action}</div>
|
|
441
|
+
</div>
|
|
442
|
+
) : (
|
|
443
|
+
<div className={clsx('text-sm font-medium', colors.title, items && 'mb-1')}>{title}</div>
|
|
444
|
+
)}
|
|
419
445
|
{message && <div className={clsx('text-xs mt-1 break-words', colors.message)}>{message}</div>}
|
|
420
446
|
{items && items.length > 0 && (
|
|
421
447
|
<ul className={clsx('text-xs space-y-1', colors.list)}>
|
|
@@ -429,6 +455,11 @@ export function AlertBanner({ variant, icon, title, message, items, children }:
|
|
|
429
455
|
)}
|
|
430
456
|
{children}
|
|
431
457
|
</div>
|
|
458
|
+
) : action ? (
|
|
459
|
+
<div className="flex min-w-0 flex-1 flex-wrap items-center justify-between gap-x-3 gap-y-1">
|
|
460
|
+
<div className={clsx('min-w-0 text-sm font-medium', colors.title)}>{title}</div>
|
|
461
|
+
<div className="shrink-0">{action}</div>
|
|
462
|
+
</div>
|
|
432
463
|
) : (
|
|
433
464
|
<div className={clsx('text-sm font-medium', colors.title)}>{title}</div>
|
|
434
465
|
)}
|
|
@@ -515,19 +546,22 @@ export function AnnotationsSection({ data }: { data: any }) {
|
|
|
515
546
|
)
|
|
516
547
|
}
|
|
517
548
|
|
|
518
|
-
export function MetadataSection({ data }: { data: any }) {
|
|
549
|
+
export function MetadataSection({ data, onNavigate }: { data: any; onNavigate?: (ref: ResourceRef) => void }) {
|
|
550
|
+
useSyncExternalStore(subscribeCRDDefinitions, getCRDDefinitionsSnapshot, getCRDDefinitionsSnapshot)
|
|
519
551
|
const meta = data.metadata
|
|
520
552
|
if (!meta) return null
|
|
553
|
+
const definition = customResourceDefinitionRef(data.apiVersion, data.kind)
|
|
521
554
|
|
|
522
555
|
return (
|
|
523
556
|
<Section title="Metadata" defaultExpanded>
|
|
524
557
|
<PropertyList>
|
|
558
|
+
{definition && <Property label="Definition" value={<ResourceLink {...definition} onNavigate={onNavigate} />} />}
|
|
525
559
|
<Property label="UID" value={meta.uid} />
|
|
526
560
|
<Property label="Resource Version" value={meta.resourceVersion} />
|
|
527
561
|
<Property label="Generation" value={meta.generation} />
|
|
528
562
|
<Property label="Created" value={meta.creationTimestamp ? (
|
|
529
563
|
<Tooltip content={new Date(meta.creationTimestamp).toLocaleString()}>
|
|
530
|
-
<span className="border-b border-dotted border-theme-text-tertiary cursor-help">{
|
|
564
|
+
<span className="border-b border-dotted border-theme-text-tertiary cursor-help">{formatRelativeAgeTime(meta.creationTimestamp)}</span>
|
|
531
565
|
</Tooltip>
|
|
532
566
|
) : '-'} />
|
|
533
567
|
</PropertyList>
|
|
@@ -727,7 +761,7 @@ export function formatKindName(kind: string): string {
|
|
|
727
761
|
pods: 'Pod', deployments: 'Deployment', daemonsets: 'DaemonSet', statefulsets: 'StatefulSet',
|
|
728
762
|
replicasets: 'ReplicaSet', services: 'Service', endpointslices: 'EndpointSlice', ingresses: 'Ingress',
|
|
729
763
|
gateways: 'Gateway', httproutes: 'HTTPRoute', grpcroutes: 'GRPCRoute',
|
|
730
|
-
tcproutes: 'TCPRoute', tlsroutes: 'TLSRoute', configmaps: 'ConfigMap',
|
|
764
|
+
tcproutes: 'TCPRoute', tlsroutes: 'TLSRoute', udproutes: 'UDPRoute', configmaps: 'ConfigMap',
|
|
731
765
|
secrets: 'Secret', jobs: 'Job', cronjobs: 'CronJob', hpas: 'HPA',
|
|
732
766
|
horizontalpodautoscalers: 'HPA', nodes: 'Node', namespaces: 'Namespace',
|
|
733
767
|
persistentvolumeclaims: 'PVC', persistentvolumes: 'PV',
|
|
@@ -784,25 +818,19 @@ export type CopyHandler = (text: string, key: string) => void
|
|
|
784
818
|
import type { TimelineEvent, Relationships, ResourceRef } from '../../types'
|
|
785
819
|
import { isChangeEvent, isK8sEvent } from '../../types'
|
|
786
820
|
import { Link } from 'lucide-react'
|
|
821
|
+
import { formatRelativeAgeTime } from '../../utils/format'
|
|
787
822
|
|
|
788
823
|
interface RelatedResourcesSectionProps {
|
|
789
824
|
relationships: Relationships | undefined
|
|
790
825
|
onNavigate?: (ref: ResourceRef) => void
|
|
791
826
|
}
|
|
792
827
|
|
|
793
|
-
function dedupeRefs(refs: ResourceRef[]): ResourceRef[] {
|
|
794
|
-
const seen = new Set<string>()
|
|
795
|
-
return refs.filter(ref => {
|
|
796
|
-
const key = `${ref.kind}/${ref.namespace}/${ref.name}`
|
|
797
|
-
if (seen.has(key)) return false
|
|
798
|
-
seen.add(key)
|
|
799
|
-
return true
|
|
800
|
-
})
|
|
801
|
-
}
|
|
802
|
-
|
|
803
828
|
export function RelatedResourcesSection({ relationships, onNavigate }: RelatedResourcesSectionProps) {
|
|
804
829
|
if (!relationships) return null
|
|
805
830
|
|
|
831
|
+
const configRefs = omitResourceRefs(relationships.configRefs ?? [], relationships.dependencies ?? [])
|
|
832
|
+
const consumers = omitResourceRefs(relationships.consumers ?? [], relationships.dependents ?? [])
|
|
833
|
+
|
|
806
834
|
const hasRelationships =
|
|
807
835
|
relationships.owner ||
|
|
808
836
|
relationships.deployment ||
|
|
@@ -820,6 +848,15 @@ export function RelatedResourcesSection({ relationships, onNavigate }: RelatedRe
|
|
|
820
848
|
(relationships.pdbs && relationships.pdbs.length > 0) ||
|
|
821
849
|
(relationships.networkPolicies && relationships.networkPolicies.length > 0) ||
|
|
822
850
|
(relationships.resourceClaims && relationships.resourceClaims.length > 0) ||
|
|
851
|
+
(relationships.dependencies && relationships.dependencies.length > 0) ||
|
|
852
|
+
(relationships.dependents && relationships.dependents.length > 0) ||
|
|
853
|
+
(relationships.monitors && relationships.monitors.length > 0) ||
|
|
854
|
+
(relationships.monitorTargets && relationships.monitorTargets.length > 0) ||
|
|
855
|
+
(relationships.backends && relationships.backends.length > 0) ||
|
|
856
|
+
(relationships.routedFrom && relationships.routedFrom.length > 0) ||
|
|
857
|
+
(relationships.protects && relationships.protects.length > 0) ||
|
|
858
|
+
(relationships.healthChecks && relationships.healthChecks.length > 0) ||
|
|
859
|
+
(relationships.stagedPolicies && relationships.stagedPolicies.length > 0) ||
|
|
823
860
|
relationships.scaleTarget
|
|
824
861
|
|
|
825
862
|
if (!hasRelationships) return null
|
|
@@ -837,43 +874,70 @@ export function RelatedResourcesSection({ relationships, onNavigate }: RelatedRe
|
|
|
837
874
|
<RelationshipGroup label="Node" refs={[relationships.node]} onNavigate={onNavigate} />
|
|
838
875
|
)}
|
|
839
876
|
{relationships.children && relationships.children.length > 0 && (
|
|
840
|
-
<RelationshipGroup label="Children" refs={
|
|
877
|
+
<RelationshipGroup label="Children" refs={dedupeResourceRefs(relationships.children)} onNavigate={onNavigate} />
|
|
841
878
|
)}
|
|
842
879
|
{relationships.services && relationships.services.length > 0 && (
|
|
843
|
-
<RelationshipGroup label="Services" refs={
|
|
880
|
+
<RelationshipGroup label="Services" refs={dedupeResourceRefs(relationships.services)} onNavigate={onNavigate} />
|
|
844
881
|
)}
|
|
845
882
|
{relationships.ingresses && relationships.ingresses.length > 0 && (
|
|
846
|
-
<RelationshipGroup label="Ingresses" refs={
|
|
883
|
+
<RelationshipGroup label="Ingresses" refs={dedupeResourceRefs(relationships.ingresses)} onNavigate={onNavigate} />
|
|
847
884
|
)}
|
|
848
885
|
{relationships.gateways && relationships.gateways.length > 0 && (
|
|
849
|
-
<RelationshipGroup label="Gateways" refs={
|
|
886
|
+
<RelationshipGroup label="Gateways" refs={dedupeResourceRefs(relationships.gateways)} onNavigate={onNavigate} />
|
|
850
887
|
)}
|
|
851
888
|
{relationships.routes && relationships.routes.length > 0 && (
|
|
852
|
-
<RelationshipGroup label="Routes" refs={
|
|
889
|
+
<RelationshipGroup label="Routes" refs={dedupeResourceRefs(relationships.routes)} onNavigate={onNavigate} />
|
|
853
890
|
)}
|
|
854
891
|
{relationships.pods && relationships.pods.length > 0 && (
|
|
855
|
-
<RelationshipGroup label="Pods" refs={
|
|
892
|
+
<RelationshipGroup label="Pods" refs={dedupeResourceRefs(relationships.pods)} onNavigate={onNavigate} />
|
|
856
893
|
)}
|
|
857
|
-
{
|
|
858
|
-
<RelationshipGroup label="Configuration" refs={
|
|
894
|
+
{configRefs.length > 0 && (
|
|
895
|
+
<RelationshipGroup label="Configuration" refs={dedupeResourceRefs(configRefs)} onNavigate={onNavigate} />
|
|
859
896
|
)}
|
|
860
|
-
{
|
|
861
|
-
<RelationshipGroup label="Used By" refs={
|
|
897
|
+
{consumers.length > 0 && (
|
|
898
|
+
<RelationshipGroup label="Used By" refs={dedupeResourceRefs(consumers)} onNavigate={onNavigate} />
|
|
862
899
|
)}
|
|
863
900
|
{relationships.scalers && relationships.scalers.length > 0 && (
|
|
864
|
-
<RelationshipGroup label="Autoscaler" refs={
|
|
901
|
+
<RelationshipGroup label="Autoscaler" refs={dedupeResourceRefs(relationships.scalers)} onNavigate={onNavigate} />
|
|
865
902
|
)}
|
|
866
903
|
{relationships.storageRefs && relationships.storageRefs.length > 0 && (
|
|
867
|
-
<RelationshipGroup label="Storage" refs={
|
|
904
|
+
<RelationshipGroup label="Storage" refs={dedupeResourceRefs(relationships.storageRefs)} onNavigate={onNavigate} />
|
|
868
905
|
)}
|
|
869
906
|
{relationships.pdbs && relationships.pdbs.length > 0 && (
|
|
870
|
-
<RelationshipGroup label="Disruption Budget" refs={
|
|
907
|
+
<RelationshipGroup label="Disruption Budget" refs={dedupeResourceRefs(relationships.pdbs)} onNavigate={onNavigate} />
|
|
871
908
|
)}
|
|
872
909
|
{relationships.networkPolicies && relationships.networkPolicies.length > 0 && (
|
|
873
|
-
<RelationshipGroup label="Network Policies" refs={
|
|
910
|
+
<RelationshipGroup label="Network Policies" refs={dedupeResourceRefs(relationships.networkPolicies)} onNavigate={onNavigate} />
|
|
874
911
|
)}
|
|
875
912
|
{relationships.resourceClaims && relationships.resourceClaims.length > 0 && (
|
|
876
|
-
<RelationshipGroup label="Resource Claims" refs={
|
|
913
|
+
<RelationshipGroup label="Resource Claims" refs={dedupeResourceRefs(relationships.resourceClaims)} onNavigate={onNavigate} />
|
|
914
|
+
)}
|
|
915
|
+
{relationships.dependencies && relationships.dependencies.length > 0 && (
|
|
916
|
+
<RelationshipGroup label="Depends On" refs={dedupeResourceRefs(relationships.dependencies)} onNavigate={onNavigate} />
|
|
917
|
+
)}
|
|
918
|
+
{relationships.dependents && relationships.dependents.length > 0 && (
|
|
919
|
+
<RelationshipGroup label="Required By" refs={dedupeResourceRefs(relationships.dependents)} onNavigate={onNavigate} />
|
|
920
|
+
)}
|
|
921
|
+
{relationships.monitors && relationships.monitors.length > 0 && (
|
|
922
|
+
<RelationshipGroup label="Monitored By" refs={dedupeResourceRefs(relationships.monitors)} onNavigate={onNavigate} />
|
|
923
|
+
)}
|
|
924
|
+
{relationships.monitorTargets && relationships.monitorTargets.length > 0 && (
|
|
925
|
+
<RelationshipGroup label="Monitors" refs={dedupeResourceRefs(relationships.monitorTargets)} onNavigate={onNavigate} />
|
|
926
|
+
)}
|
|
927
|
+
{relationships.backends && relationships.backends.length > 0 && (
|
|
928
|
+
<RelationshipGroup label="Routes To" refs={dedupeResourceRefs(relationships.backends)} onNavigate={onNavigate} />
|
|
929
|
+
)}
|
|
930
|
+
{relationships.routedFrom && relationships.routedFrom.length > 0 && (
|
|
931
|
+
<RelationshipGroup label="Routed From" refs={dedupeResourceRefs(relationships.routedFrom)} onNavigate={onNavigate} />
|
|
932
|
+
)}
|
|
933
|
+
{relationships.protects && relationships.protects.length > 0 && (
|
|
934
|
+
<RelationshipGroup label="Selects" refs={dedupeResourceRefs(relationships.protects)} onNavigate={onNavigate} />
|
|
935
|
+
)}
|
|
936
|
+
{relationships.healthChecks && relationships.healthChecks.length > 0 && (
|
|
937
|
+
<RelationshipGroup label="Health Checks" refs={dedupeResourceRefs(relationships.healthChecks)} onNavigate={onNavigate} />
|
|
938
|
+
)}
|
|
939
|
+
{relationships.stagedPolicies && relationships.stagedPolicies.length > 0 && (
|
|
940
|
+
<RelationshipGroup label="Staged Policies" refs={dedupeResourceRefs(relationships.stagedPolicies)} onNavigate={onNavigate} />
|
|
877
941
|
)}
|
|
878
942
|
{relationships.scaleTarget && (
|
|
879
943
|
<RelationshipGroup label="Scale Target" refs={[relationships.scaleTarget]} onNavigate={onNavigate} />
|
|
@@ -926,7 +990,7 @@ export interface ResourceRefBadgeProps {
|
|
|
926
990
|
/** Reusable chip/badge for showing a related resource with click-to-navigate */
|
|
927
991
|
export function ResourceRefBadge({ resourceRef, onClick, wrapAtSeparator }: ResourceRefBadgeProps) {
|
|
928
992
|
const kindClass = getKindColor(resourceRef.kind)
|
|
929
|
-
const kindName = formatKindForRef(resourceRef.kind)
|
|
993
|
+
const kindName = formatKindForRef(resourceRef.kind, resourceRef.group)
|
|
930
994
|
const content = wrapAtSeparator ? (
|
|
931
995
|
<>
|
|
932
996
|
<span className="shrink-0 opacity-60">{kindName}/</span>
|
|
@@ -989,8 +1053,10 @@ export function ResourceLink({ name, kind, namespace = '', group, label, onNavig
|
|
|
989
1053
|
)
|
|
990
1054
|
}
|
|
991
1055
|
|
|
992
|
-
function formatKindForRef(kind: string): string {
|
|
1056
|
+
function formatKindForRef(kind: string, group?: string): string {
|
|
993
1057
|
const k = kind.toLowerCase()
|
|
1058
|
+
// A Knative Service shares its kind with core Services; use Knative's own short name.
|
|
1059
|
+
if (k === 'service' && group === 'serving.knative.dev') return 'ksvc'
|
|
994
1060
|
const shortNames: Record<string, string> = {
|
|
995
1061
|
deployment: 'deploy',
|
|
996
1062
|
daemonset: 'ds',
|
|
@@ -1003,6 +1069,7 @@ function formatKindForRef(kind: string): string {
|
|
|
1003
1069
|
httproute: 'hr',
|
|
1004
1070
|
grpcroute: 'grpc',
|
|
1005
1071
|
tcproute: 'tcp',
|
|
1072
|
+
udproute: 'udp',
|
|
1006
1073
|
tlsroute: 'tls',
|
|
1007
1074
|
secret: 'secret',
|
|
1008
1075
|
pod: 'pod',
|
|
@@ -19,7 +19,9 @@ export type { SelectMenuOption } from './SelectMenu'
|
|
|
19
19
|
export { Input } from './Input'
|
|
20
20
|
export { FilterPill } from './FilterPill'
|
|
21
21
|
export type { FilterPillTone } from './FilterPill'
|
|
22
|
-
export { StatusDot, mapHealthToTone } from './status-tone'
|
|
22
|
+
export { StatusDot, mapHealthToTone, toneFillClass, toneTextClass, worseTone } from './status-tone'
|
|
23
|
+
export { RefLink, type NavigateToRef } from './RefLink'
|
|
24
|
+
export { FoldSection, SectionHeading, type FoldSummary } from './FoldSection'
|
|
23
25
|
export type { StatusTone, StatusDotProps } from './status-tone'
|
|
24
26
|
export { DialogPortal } from './DialogPortal'
|
|
25
27
|
export { ConfirmDialog } from './ConfirmDialog'
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Every editor feature monaco-editor's editor.main entry registers (context menu,
|
|
2
|
+
// comments, multi-cursor, line operations, bracket matching, sticky scroll, quick
|
|
3
|
+
// access, ...), without its language definitions and the TS/JSON/CSS/HTML language
|
|
4
|
+
// services, whose workers this runtime does not ship. editor.api alone registers none
|
|
5
|
+
// of these, so dropping this import silently strips them from every editor.
|
|
6
|
+
import 'monaco-editor/editor/contrib/anchorSelect/browser/anchorSelect.js'
|
|
7
|
+
import 'monaco-editor/editor/contrib/bracketMatching/browser/bracketMatching.js'
|
|
8
|
+
import 'monaco-editor/editor/contrib/caretOperations/browser/transpose.js'
|
|
9
|
+
import 'monaco-editor/editor/contrib/clipboard/browser/clipboard.js'
|
|
10
|
+
import 'monaco-editor/editor/contrib/codeAction/browser/codeActionContributions.js'
|
|
11
|
+
import 'monaco-editor/editor/browser/widget/codeEditor/codeEditorWidget.js'
|
|
12
|
+
import 'monaco-editor/editor/contrib/codelens/browser/codelensController.js'
|
|
13
|
+
import 'monaco-editor/editor/contrib/colorPicker/browser/colorPickerContribution.js'
|
|
14
|
+
import 'monaco-editor/editor/contrib/comment/browser/comment.js'
|
|
15
|
+
import 'monaco-editor/editor/contrib/contextmenu/browser/contextmenu.js'
|
|
16
|
+
import 'monaco-editor/editor/contrib/cursorUndo/browser/cursorUndo.js'
|
|
17
|
+
import 'monaco-editor/editor/browser/widget/diffEditor/diffEditor.contribution.js'
|
|
18
|
+
import 'monaco-editor/editor/contrib/diffEditorBreadcrumbs/browser/contribution.js'
|
|
19
|
+
import 'monaco-editor/editor/contrib/dnd/browser/dnd.js'
|
|
20
|
+
import 'monaco-editor/editor/contrib/documentSymbols/browser/documentSymbols.js'
|
|
21
|
+
import 'monaco-editor/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.js'
|
|
22
|
+
import 'monaco-editor/features/find/register.js'
|
|
23
|
+
import 'monaco-editor/editor/contrib/floatingMenu/browser/floatingMenu.contribution.js'
|
|
24
|
+
import 'monaco-editor/editor/contrib/folding/browser/folding.js'
|
|
25
|
+
import 'monaco-editor/editor/contrib/fontZoom/browser/fontZoom.js'
|
|
26
|
+
import 'monaco-editor/editor/contrib/format/browser/formatActions.js'
|
|
27
|
+
import 'monaco-editor/editor/contrib/gotoError/browser/gotoError.js'
|
|
28
|
+
import 'monaco-editor/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.js'
|
|
29
|
+
import 'monaco-editor/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.js'
|
|
30
|
+
import 'monaco-editor/editor/contrib/gpu/browser/gpuActions.js'
|
|
31
|
+
import 'monaco-editor/editor/contrib/hover/browser/hoverContribution.js'
|
|
32
|
+
import 'monaco-editor/editor/contrib/indentation/browser/indentation.js'
|
|
33
|
+
import 'monaco-editor/editor/contrib/inlayHints/browser/inlayHintsContribution.js'
|
|
34
|
+
import 'monaco-editor/editor/contrib/inlineCompletions/browser/inlineCompletions.contribution.js'
|
|
35
|
+
import 'monaco-editor/editor/contrib/inlineProgress/browser/inlineProgress.js'
|
|
36
|
+
import 'monaco-editor/editor/contrib/inPlaceReplace/browser/inPlaceReplace.js'
|
|
37
|
+
import 'monaco-editor/editor/contrib/insertFinalNewLine/browser/insertFinalNewLine.js'
|
|
38
|
+
import 'monaco-editor/editor/standalone/browser/inspectTokens/inspectTokens.js'
|
|
39
|
+
import 'monaco-editor/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.js'
|
|
40
|
+
import 'monaco-editor/editor/contrib/lineSelection/browser/lineSelection.js'
|
|
41
|
+
import 'monaco-editor/editor/contrib/linesOperations/browser/linesOperations.js'
|
|
42
|
+
import 'monaco-editor/editor/contrib/linkedEditing/browser/linkedEditing.js'
|
|
43
|
+
import 'monaco-editor/editor/contrib/links/browser/links.js'
|
|
44
|
+
import 'monaco-editor/editor/contrib/longLinesHelper/browser/longLinesHelper.js'
|
|
45
|
+
import 'monaco-editor/editor/contrib/middleScroll/browser/middleScroll.contribution.js'
|
|
46
|
+
import 'monaco-editor/editor/contrib/multicursor/browser/multicursor.js'
|
|
47
|
+
import 'monaco-editor/editor/contrib/parameterHints/browser/parameterHints.js'
|
|
48
|
+
import 'monaco-editor/editor/contrib/placeholderText/browser/placeholderText.contribution.js'
|
|
49
|
+
import 'monaco-editor/editor/standalone/browser/quickAccess/standaloneCommandsQuickAccess.js'
|
|
50
|
+
import 'monaco-editor/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.js'
|
|
51
|
+
import 'monaco-editor/editor/standalone/browser/quickAccess/standaloneGotoSymbolQuickAccess.js'
|
|
52
|
+
import 'monaco-editor/editor/contrib/readOnlyMessage/browser/contribution.js'
|
|
53
|
+
import 'monaco-editor/editor/standalone/browser/referenceSearch/standaloneReferenceSearch.js'
|
|
54
|
+
import 'monaco-editor/editor/contrib/rename/browser/rename.js'
|
|
55
|
+
import 'monaco-editor/editor/contrib/sectionHeaders/browser/sectionHeaders.js'
|
|
56
|
+
import 'monaco-editor/editor/contrib/semanticTokens/browser/viewportSemanticTokens.js'
|
|
57
|
+
import 'monaco-editor/editor/contrib/smartSelect/browser/smartSelect.js'
|
|
58
|
+
import 'monaco-editor/editor/contrib/snippet/browser/snippetController2.js'
|
|
59
|
+
import 'monaco-editor/editor/contrib/stickyScroll/browser/stickyScrollContribution.js'
|
|
60
|
+
import 'monaco-editor/editor/contrib/suggest/browser/suggestInlineCompletions.js'
|
|
61
|
+
import 'monaco-editor/editor/standalone/browser/toggleHighContrast/toggleHighContrast.js'
|
|
62
|
+
import 'monaco-editor/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode.js'
|
|
63
|
+
import 'monaco-editor/editor/contrib/tokenization/browser/tokenization.js'
|
|
64
|
+
import 'monaco-editor/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.js'
|
|
65
|
+
import 'monaco-editor/editor/contrib/unusualLineTerminators/browser/unusualLineTerminators.js'
|
|
66
|
+
import 'monaco-editor/editor/contrib/wordHighlighter/browser/wordHighlighter.js'
|
|
67
|
+
import 'monaco-editor/editor/contrib/wordOperations/browser/wordOperations.js'
|
|
68
|
+
import 'monaco-editor/editor/contrib/wordPartOperations/browser/wordPartOperations.js'
|
|
69
|
+
import 'monaco-editor/editor/browser/coreCommands.js'
|
|
70
|
+
import 'monaco-editor/editor/contrib/caretOperations/browser/caretOperations.js'
|
|
71
|
+
import 'monaco-editor/editor/contrib/dropOrPasteInto/browser/copyPasteContribution.js'
|
|
72
|
+
import 'monaco-editor/editor/contrib/find/browser/findController.js'
|
|
73
|
+
import 'monaco-editor/editor/contrib/gotoSymbol/browser/goToCommands.js'
|
|
74
|
+
import 'monaco-editor/editor/contrib/gotoError/browser/markerSelectionStatus.js'
|
|
75
|
+
import 'monaco-editor/editor/contrib/semanticTokens/browser/documentSemanticTokens.js'
|
|
76
|
+
import 'monaco-editor/editor/contrib/suggest/browser/suggestController.js'
|
|
77
|
+
import 'monaco-editor/editor/common/standaloneStrings.js'
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
/// <reference path="../../monaco-deep.d.ts" />
|
|
2
2
|
|
|
3
3
|
import { loader } from '@monaco-editor/react'
|
|
4
|
-
import * as monaco from 'monaco-editor/
|
|
4
|
+
import * as monaco from 'monaco-editor/editor/editor.api'
|
|
5
5
|
// Tokenizers only — the set the YAML editor and the pod file viewer hand to
|
|
6
6
|
// Monaco. JSON deliberately absent: its language lives in vs/language/json and
|
|
7
7
|
// spawns a validation worker this runtime does not ship; viewers highlight
|
|
8
8
|
// JSON with the YAML tokenizer, which covers it.
|
|
9
|
-
import 'monaco-editor/
|
|
10
|
-
import 'monaco-editor/
|
|
11
|
-
import 'monaco-editor/
|
|
12
|
-
import 'monaco-editor/
|
|
13
|
-
import 'monaco-editor/
|
|
14
|
-
import 'monaco-editor/
|
|
15
|
-
import 'monaco-editor/
|
|
16
|
-
import 'monaco-editor/
|
|
17
|
-
import 'monaco-editor/
|
|
18
|
-
import 'monaco-editor/
|
|
19
|
-
import 'monaco-editor/
|
|
20
|
-
import '
|
|
21
|
-
import 'monaco-editor/esm/vs/editor/contrib/folding/browser/folding.js'
|
|
22
|
-
import 'monaco-editor/esm/vs/editor/contrib/format/browser/formatActions.js'
|
|
23
|
-
import 'monaco-editor/esm/vs/editor/contrib/gotoError/browser/gotoError.js'
|
|
24
|
-
import 'monaco-editor/esm/vs/editor/contrib/hover/browser/hoverContribution.js'
|
|
25
|
-
import 'monaco-editor/esm/vs/editor/contrib/suggest/browser/suggestController.js'
|
|
9
|
+
import 'monaco-editor/languages/definitions/yaml/register'
|
|
10
|
+
import 'monaco-editor/languages/definitions/xml/register'
|
|
11
|
+
import 'monaco-editor/languages/definitions/html/register'
|
|
12
|
+
import 'monaco-editor/languages/definitions/css/register'
|
|
13
|
+
import 'monaco-editor/languages/definitions/javascript/register'
|
|
14
|
+
import 'monaco-editor/languages/definitions/typescript/register'
|
|
15
|
+
import 'monaco-editor/languages/definitions/python/register'
|
|
16
|
+
import 'monaco-editor/languages/definitions/shell/register'
|
|
17
|
+
import 'monaco-editor/languages/definitions/markdown/register'
|
|
18
|
+
import 'monaco-editor/languages/definitions/ini/register'
|
|
19
|
+
import 'monaco-editor/languages/definitions/dockerfile/register'
|
|
20
|
+
import './monacoEditorFeatures'
|
|
26
21
|
|
|
27
22
|
type MonacoGlobal = typeof globalThis & {
|
|
28
23
|
MonacoEnvironment?: {
|
|
@@ -37,7 +32,7 @@ export async function ensureMonaco() {
|
|
|
37
32
|
;(globalThis as MonacoGlobal).MonacoEnvironment = {
|
|
38
33
|
getWorker() {
|
|
39
34
|
return new Worker(
|
|
40
|
-
new URL('monaco-editor/
|
|
35
|
+
new URL('monaco-editor/editor/editor.worker.js', import.meta.url),
|
|
41
36
|
{
|
|
42
37
|
name: 'radar-monaco-editor',
|
|
43
38
|
type: 'module',
|