@skyhook-io/k8s-ui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +63 -0
- package/src/components/dock/BottomDock.tsx +204 -0
- package/src/components/dock/DockContext.tsx +212 -0
- package/src/components/dock/TerminalTab.tsx +333 -0
- package/src/components/dock/index.ts +3 -0
- package/src/components/gitops/GitOpsActions.tsx +227 -0
- package/src/components/gitops/GitOpsStatusBadge.tsx +221 -0
- package/src/components/gitops/ManagedResourcesList.tsx +210 -0
- package/src/components/gitops/SyncCountdown.tsx +146 -0
- package/src/components/gitops/index.ts +4 -0
- package/src/components/logs/JsonLogLine.tsx +90 -0
- package/src/components/logs/LogCore.tsx +553 -0
- package/src/components/logs/LogToolbarSelects.tsx +74 -0
- package/src/components/logs/LogsViewer.tsx +146 -0
- package/src/components/logs/WorkloadLogsViewer.tsx +263 -0
- package/src/components/logs/index.ts +13 -0
- package/src/components/logs/useLogBuffer.ts +138 -0
- package/src/components/logs/useLogSearch.ts +151 -0
- package/src/components/logs/useLogStream.ts +61 -0
- package/src/components/resources/ResourcesView.tsx +5494 -0
- package/src/components/resources/index.ts +17 -0
- package/src/components/resources/renderers/AlertRenderer.tsx +166 -0
- package/src/components/resources/renderers/ArgoApplicationRenderer.tsx +233 -0
- package/src/components/resources/renderers/CNPGBackupRenderer.tsx +89 -0
- package/src/components/resources/renderers/CNPGClusterRenderer.tsx +194 -0
- package/src/components/resources/renderers/CNPGPoolerRenderer.tsx +79 -0
- package/src/components/resources/renderers/CNPGScheduledBackupRenderer.tsx +68 -0
- package/src/components/resources/renderers/CertificateRenderer.tsx +209 -0
- package/src/components/resources/renderers/CertificateRequestRenderer.tsx +123 -0
- package/src/components/resources/renderers/ChallengeRenderer.tsx +111 -0
- package/src/components/resources/renderers/ClusterComplianceReportRenderer.tsx +164 -0
- package/src/components/resources/renderers/ClusterExternalSecretRenderer.tsx +140 -0
- package/src/components/resources/renderers/ClusterIssuerRenderer.tsx +153 -0
- package/src/components/resources/renderers/ConfigAuditReportRenderer.tsx +221 -0
- package/src/components/resources/renderers/ConfigMapRenderer.tsx +124 -0
- package/src/components/resources/renderers/CronJobRenderer.tsx +86 -0
- package/src/components/resources/renderers/EventRenderer.tsx +175 -0
- package/src/components/resources/renderers/ExposedSecretReportRenderer.tsx +119 -0
- package/src/components/resources/renderers/ExternalSecretRenderer.tsx +172 -0
- package/src/components/resources/renderers/FluxHelmReleaseRenderer.tsx +242 -0
- package/src/components/resources/renderers/GRPCRouteRenderer.tsx +263 -0
- package/src/components/resources/renderers/GatewayClassRenderer.tsx +68 -0
- package/src/components/resources/renderers/GatewayRenderer.tsx +218 -0
- package/src/components/resources/renderers/GenericRenderer.tsx +476 -0
- package/src/components/resources/renderers/GitRepositoryRenderer.tsx +154 -0
- package/src/components/resources/renderers/HPARenderer.tsx +164 -0
- package/src/components/resources/renderers/HTTPRouteRenderer.tsx +303 -0
- package/src/components/resources/renderers/HelmRepositoryRenderer.tsx +167 -0
- package/src/components/resources/renderers/IngressClassRenderer.tsx +49 -0
- package/src/components/resources/renderers/IngressRenderer.tsx +104 -0
- package/src/components/resources/renderers/IstioAuthorizationPolicyRenderer.tsx +175 -0
- package/src/components/resources/renderers/IstioDestinationRuleRenderer.tsx +176 -0
- package/src/components/resources/renderers/IstioGatewayRenderer.tsx +125 -0
- package/src/components/resources/renderers/IstioPeerAuthenticationRenderer.tsx +84 -0
- package/src/components/resources/renderers/IstioServiceEntryRenderer.tsx +112 -0
- package/src/components/resources/renderers/IstioVirtualServiceRenderer.tsx +288 -0
- package/src/components/resources/renderers/JobRenderer.tsx +103 -0
- package/src/components/resources/renderers/KarpenterEC2NodeClassRenderer.tsx +157 -0
- package/src/components/resources/renderers/KarpenterNodeClaimRenderer.tsx +188 -0
- package/src/components/resources/renderers/KarpenterNodePoolRenderer.tsx +148 -0
- package/src/components/resources/renderers/KedaScaledJobRenderer.tsx +90 -0
- package/src/components/resources/renderers/KedaScaledObjectRenderer.tsx +136 -0
- package/src/components/resources/renderers/KedaTriggerAuthRenderer.tsx +151 -0
- package/src/components/resources/renderers/KnativeConfigurationRenderer.tsx +70 -0
- package/src/components/resources/renderers/KnativeEventingRenderer.tsx +309 -0
- package/src/components/resources/renderers/KnativeFlowRenderer.tsx +142 -0
- package/src/components/resources/renderers/KnativeNetworkingRenderer.tsx +232 -0
- package/src/components/resources/renderers/KnativeRevisionRenderer.tsx +97 -0
- package/src/components/resources/renderers/KnativeRouteRenderer.tsx +74 -0
- package/src/components/resources/renderers/KnativeServiceRenderer.tsx +138 -0
- package/src/components/resources/renderers/KnativeSourceRenderer.tsx +220 -0
- package/src/components/resources/renderers/KustomizationRenderer.tsx +151 -0
- package/src/components/resources/renderers/KyvernoPolicyReportRenderer.tsx +352 -0
- package/src/components/resources/renderers/LeaseRenderer.tsx +93 -0
- package/src/components/resources/renderers/NetworkPolicyRenderer.tsx +208 -0
- package/src/components/resources/renderers/NodeRenderer.tsx +282 -0
- package/src/components/resources/renderers/OCIRepositoryRenderer.tsx +153 -0
- package/src/components/resources/renderers/OrderRenderer.tsx +108 -0
- package/src/components/resources/renderers/PVCRenderer.tsx +98 -0
- package/src/components/resources/renderers/PersistentVolumeRenderer.tsx +138 -0
- package/src/components/resources/renderers/PodDisruptionBudgetRenderer.tsx +126 -0
- package/src/components/resources/renderers/PodMonitorRenderer.tsx +63 -0
- package/src/components/resources/renderers/PodRenderer.tsx +677 -0
- package/src/components/resources/renderers/PriorityClassRenderer.tsx +50 -0
- package/src/components/resources/renderers/PrometheusRuleRenderer.tsx +62 -0
- package/src/components/resources/renderers/ReplicaSetRenderer.tsx +71 -0
- package/src/components/resources/renderers/RoleBindingRenderer.tsx +97 -0
- package/src/components/resources/renderers/RoleRenderer.tsx +192 -0
- package/src/components/resources/renderers/RolloutRenderer.tsx +227 -0
- package/src/components/resources/renderers/RuntimeClassRenderer.tsx +75 -0
- package/src/components/resources/renderers/SbomReportRenderer.tsx +98 -0
- package/src/components/resources/renderers/SealedSecretRenderer.tsx +121 -0
- package/src/components/resources/renderers/SecretRenderer.tsx +321 -0
- package/src/components/resources/renderers/SecretStoreRenderer.tsx +111 -0
- package/src/components/resources/renderers/ServiceAccountRenderer.tsx +81 -0
- package/src/components/resources/renderers/ServiceMonitorRenderer.tsx +65 -0
- package/src/components/resources/renderers/ServiceRenderer.tsx +98 -0
- package/src/components/resources/renderers/SimpleRouteRenderer.tsx +195 -0
- package/src/components/resources/renderers/StorageClassRenderer.tsx +82 -0
- package/src/components/resources/renderers/TraefikIngressRouteRenderer.tsx +257 -0
- package/src/components/resources/renderers/VPARenderer.tsx +193 -0
- package/src/components/resources/renderers/VeleroBSLRenderer.tsx +73 -0
- package/src/components/resources/renderers/VeleroBackupRenderer.tsx +193 -0
- package/src/components/resources/renderers/VeleroRestoreRenderer.tsx +161 -0
- package/src/components/resources/renderers/VeleroScheduleRenderer.tsx +134 -0
- package/src/components/resources/renderers/VeleroVSLRenderer.tsx +36 -0
- package/src/components/resources/renderers/VulnerabilityReportRenderer.tsx +347 -0
- package/src/components/resources/renderers/WebhookConfigRenderer.tsx +156 -0
- package/src/components/resources/renderers/WorkflowRenderer.tsx +202 -0
- package/src/components/resources/renderers/WorkflowTemplateRenderer.tsx +91 -0
- package/src/components/resources/renderers/WorkloadRenderer.tsx +311 -0
- package/src/components/resources/renderers/argo-cells.tsx +118 -0
- package/src/components/resources/renderers/certmanager-cells.tsx +164 -0
- package/src/components/resources/renderers/cnpg-cells.tsx +161 -0
- package/src/components/resources/renderers/eso-cells.tsx +115 -0
- package/src/components/resources/renderers/flux-cells.tsx +253 -0
- package/src/components/resources/renderers/index.ts +105 -0
- package/src/components/resources/renderers/istio-cells.tsx +210 -0
- package/src/components/resources/renderers/karpenter-cells.tsx +107 -0
- package/src/components/resources/renderers/keda-cells.tsx +94 -0
- package/src/components/resources/renderers/knative-cells.tsx +396 -0
- package/src/components/resources/renderers/kyverno-cells.tsx +85 -0
- package/src/components/resources/renderers/prometheus-cells.tsx +74 -0
- package/src/components/resources/renderers/traefik-cells.tsx +120 -0
- package/src/components/resources/renderers/trivy-cells.tsx +153 -0
- package/src/components/resources/renderers/trivy-shared.tsx +67 -0
- package/src/components/resources/renderers/velero-cells.tsx +164 -0
- package/src/components/resources/resource-utils-argo.ts +155 -0
- package/src/components/resources/resource-utils-certmanager.ts +198 -0
- package/src/components/resources/resource-utils-cnpg.ts +344 -0
- package/src/components/resources/resource-utils-eso.ts +385 -0
- package/src/components/resources/resource-utils-flux.ts +186 -0
- package/src/components/resources/resource-utils-istio.ts +372 -0
- package/src/components/resources/resource-utils-karpenter.ts +150 -0
- package/src/components/resources/resource-utils-keda.ts +203 -0
- package/src/components/resources/resource-utils-knative.ts +218 -0
- package/src/components/resources/resource-utils-kyverno.ts +224 -0
- package/src/components/resources/resource-utils-prometheus.ts +159 -0
- package/src/components/resources/resource-utils-traefik.ts +180 -0
- package/src/components/resources/resource-utils-trivy.ts +146 -0
- package/src/components/resources/resource-utils-velero.ts +293 -0
- package/src/components/resources/resource-utils.ts +1558 -0
- package/src/components/shared/EditableYamlView.tsx +302 -0
- package/src/components/shared/ResourceActionsBar.tsx +924 -0
- package/src/components/shared/ResourceRendererDispatch.tsx +557 -0
- package/src/components/shared/index.ts +3 -0
- package/src/components/timeline/index.ts +1 -0
- package/src/components/timeline/shared.tsx +614 -0
- package/src/components/topology/GroupNode.tsx +198 -0
- package/src/components/topology/K8sResourceNode.tsx +440 -0
- package/src/components/topology/TopologyControls.tsx +62 -0
- package/src/components/topology/TopologyFilterSidebar.tsx +377 -0
- package/src/components/topology/TopologyGraph.tsx +748 -0
- package/src/components/topology/TopologySearch.tsx +304 -0
- package/src/components/topology/index.ts +7 -0
- package/src/components/topology/layout.ts +734 -0
- package/src/components/topology/layout.worker.ts +272 -0
- package/src/components/topology/topology.css +129 -0
- package/src/components/ui/CodeViewer.tsx +451 -0
- package/src/components/ui/ConfirmDialog.tsx +188 -0
- package/src/components/ui/ForceDeleteConfirmDialog.tsx +57 -0
- package/src/components/ui/HealthRing.tsx +72 -0
- package/src/components/ui/MetricsChart.tsx +259 -0
- package/src/components/ui/ResourceBar.tsx +68 -0
- package/src/components/ui/Toast.tsx +225 -0
- package/src/components/ui/Tooltip.tsx +165 -0
- package/src/components/ui/YamlEditor.tsx +280 -0
- package/src/components/ui/drawer-components.tsx +792 -0
- package/src/components/ui/index.ts +10 -0
- package/src/components/workload/ResourceDetailDrawer.tsx +158 -0
- package/src/components/workload/WorkloadView.tsx +1109 -0
- package/src/components/workload/index.ts +2 -0
- package/src/hooks/index.ts +9 -0
- package/src/hooks/useAnimatedUnmount.ts +30 -0
- package/src/hooks/useKeyboardShortcuts.tsx +336 -0
- package/src/hooks/useRefreshAnimation.ts +58 -0
- package/src/index.ts +35 -0
- package/src/types/core.ts +894 -0
- package/src/types/gitops.ts +458 -0
- package/src/types/index.ts +2 -0
- package/src/utils/animation.ts +40 -0
- package/src/utils/api-resources.ts +185 -0
- package/src/utils/badge-colors.ts +399 -0
- package/src/utils/context-name.ts +72 -0
- package/src/utils/download.ts +19 -0
- package/src/utils/format.ts +233 -0
- package/src/utils/index.ts +10 -0
- package/src/utils/log-format.ts +300 -0
- package/src/utils/navigation.ts +119 -0
- package/src/utils/resource-hierarchy.ts +630 -0
- package/src/utils/resource-icons.ts +206 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Cpu } from 'lucide-react'
|
|
2
|
+
import { Section, PropertyList, Property, ConditionsSection, AlertBanner, ResourceLink } from '../../ui/drawer-components'
|
|
3
|
+
import {
|
|
4
|
+
getScaledObjectStatus,
|
|
5
|
+
getScaledObjectTarget,
|
|
6
|
+
getScaledObjectReplicas,
|
|
7
|
+
getScaledObjectTriggers,
|
|
8
|
+
getScaledObjectHpaName,
|
|
9
|
+
getScaledObjectLastActiveTime,
|
|
10
|
+
getScaledObjectPollingInterval,
|
|
11
|
+
getScaledObjectCooldownPeriod,
|
|
12
|
+
} from '../resource-utils-keda'
|
|
13
|
+
|
|
14
|
+
interface KedaScaledObjectRendererProps {
|
|
15
|
+
data: any
|
|
16
|
+
onNavigate?: (ref: { kind: string; namespace: string; name: string }) => void
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function KedaScaledObjectRenderer({ data, onNavigate }: KedaScaledObjectRendererProps) {
|
|
20
|
+
const status = data.status || {}
|
|
21
|
+
const conditions = status.conditions || []
|
|
22
|
+
|
|
23
|
+
const soStatus = getScaledObjectStatus(data)
|
|
24
|
+
const triggers = getScaledObjectTriggers(data)
|
|
25
|
+
const fallback = data.spec?.fallback
|
|
26
|
+
|
|
27
|
+
// Problem detection
|
|
28
|
+
const isPaused = soStatus.text === 'Paused'
|
|
29
|
+
const isFallback = soStatus.text === 'Fallback'
|
|
30
|
+
const isNotReady = soStatus.level === 'unhealthy'
|
|
31
|
+
|
|
32
|
+
const readyCond = conditions.find((c: any) => c.type === 'Ready')
|
|
33
|
+
const fallbackCond = conditions.find((c: any) => c.type === 'Fallback')
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<>
|
|
37
|
+
{/* Problem alerts */}
|
|
38
|
+
{isFallback && (
|
|
39
|
+
<AlertBanner
|
|
40
|
+
variant="error"
|
|
41
|
+
title="Fallback Active"
|
|
42
|
+
message={fallbackCond?.message || 'KEDA is using fallback replicas because triggers are failing.'}
|
|
43
|
+
/>
|
|
44
|
+
)}
|
|
45
|
+
{isNotReady && !isFallback && (
|
|
46
|
+
<AlertBanner
|
|
47
|
+
variant="error"
|
|
48
|
+
title="ScaledObject Not Ready"
|
|
49
|
+
message={readyCond?.message || 'The ScaledObject is not in a ready state.'}
|
|
50
|
+
/>
|
|
51
|
+
)}
|
|
52
|
+
{isPaused && (
|
|
53
|
+
<AlertBanner
|
|
54
|
+
variant="warning"
|
|
55
|
+
title="Scaling Paused"
|
|
56
|
+
message="Autoscaling is paused via annotation."
|
|
57
|
+
/>
|
|
58
|
+
)}
|
|
59
|
+
|
|
60
|
+
{/* Scaling section */}
|
|
61
|
+
<Section title="Scaling" icon={Cpu}>
|
|
62
|
+
<PropertyList>
|
|
63
|
+
<Property label="Target" value={(() => {
|
|
64
|
+
const target = data.spec?.scaleTargetRef
|
|
65
|
+
if (target?.name) {
|
|
66
|
+
return (
|
|
67
|
+
<ResourceLink
|
|
68
|
+
name={target.name}
|
|
69
|
+
kind={(target.kind || 'Deployment').toLowerCase() + 's'}
|
|
70
|
+
namespace={data.metadata?.namespace || ''}
|
|
71
|
+
label={getScaledObjectTarget(data)}
|
|
72
|
+
onNavigate={onNavigate}
|
|
73
|
+
/>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
return getScaledObjectTarget(data)
|
|
77
|
+
})()} />
|
|
78
|
+
<Property label="Replicas" value={getScaledObjectReplicas(data)} />
|
|
79
|
+
<Property label="Polling Interval" value={`${getScaledObjectPollingInterval(data)}s`} />
|
|
80
|
+
<Property label="Cooldown Period" value={`${getScaledObjectCooldownPeriod(data)}s`} />
|
|
81
|
+
<Property label="Generated HPA" value={(() => {
|
|
82
|
+
const hpaName = getScaledObjectHpaName(data)
|
|
83
|
+
if (hpaName && hpaName !== '-') {
|
|
84
|
+
return <ResourceLink name={hpaName} kind="horizontalpodautoscalers" namespace={data.metadata?.namespace || ''} onNavigate={onNavigate} />
|
|
85
|
+
}
|
|
86
|
+
return hpaName
|
|
87
|
+
})()} />
|
|
88
|
+
<Property label="Last Active" value={getScaledObjectLastActiveTime(data)} />
|
|
89
|
+
</PropertyList>
|
|
90
|
+
{fallback && (
|
|
91
|
+
<div className="mt-2 pt-2 border-t border-theme-border">
|
|
92
|
+
<div className="text-xs font-medium text-theme-text-secondary uppercase tracking-wider mb-1">Fallback</div>
|
|
93
|
+
<PropertyList>
|
|
94
|
+
<Property label="Failure Threshold" value={String(fallback.failureThreshold ?? '-')} />
|
|
95
|
+
<Property label="Replicas" value={String(fallback.replicas ?? '-')} />
|
|
96
|
+
</PropertyList>
|
|
97
|
+
</div>
|
|
98
|
+
)}
|
|
99
|
+
</Section>
|
|
100
|
+
|
|
101
|
+
{/* Triggers section */}
|
|
102
|
+
{triggers.length > 0 && (
|
|
103
|
+
<Section title={`Triggers (${triggers.length})`} defaultExpanded>
|
|
104
|
+
<div className="space-y-2">
|
|
105
|
+
{triggers.map((trigger, i) => (
|
|
106
|
+
<div key={i} className="bg-theme-elevated/30 rounded p-2">
|
|
107
|
+
<div className="flex items-center gap-2 text-sm">
|
|
108
|
+
<span className="text-theme-text-primary font-medium">{trigger.type}</span>
|
|
109
|
+
{trigger.name && (
|
|
110
|
+
<span className="text-theme-text-tertiary">({trigger.name})</span>
|
|
111
|
+
)}
|
|
112
|
+
{trigger.authenticationRef && (
|
|
113
|
+
<span className="px-1.5 py-0.5 bg-theme-hover rounded text-xs text-theme-text-secondary">
|
|
114
|
+
auth: {trigger.authenticationRef.name}
|
|
115
|
+
</span>
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
{trigger.metadata && Object.keys(trigger.metadata).length > 0 && (
|
|
119
|
+
<div className="mt-1 flex flex-wrap gap-1">
|
|
120
|
+
{Object.entries(trigger.metadata).map(([k, v]) => (
|
|
121
|
+
<span key={k} className="px-1.5 py-0.5 bg-theme-hover rounded text-xs text-theme-text-secondary">
|
|
122
|
+
{k}: {v}
|
|
123
|
+
</span>
|
|
124
|
+
))}
|
|
125
|
+
</div>
|
|
126
|
+
)}
|
|
127
|
+
</div>
|
|
128
|
+
))}
|
|
129
|
+
</div>
|
|
130
|
+
</Section>
|
|
131
|
+
)}
|
|
132
|
+
|
|
133
|
+
<ConditionsSection conditions={conditions} />
|
|
134
|
+
</>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { KeyRound, Server, Cloud, Shield } from 'lucide-react'
|
|
2
|
+
import { Section, PropertyList, Property, ConditionsSection, ResourceLink } from '../../ui/drawer-components'
|
|
3
|
+
import {
|
|
4
|
+
getTriggerAuthSecretRefs,
|
|
5
|
+
getTriggerAuthEnvVars,
|
|
6
|
+
} from '../resource-utils-keda'
|
|
7
|
+
|
|
8
|
+
interface KedaTriggerAuthRendererProps {
|
|
9
|
+
data: any
|
|
10
|
+
onNavigate?: (ref: { kind: string; namespace: string; name: string }) => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function KedaTriggerAuthRenderer({ data, onNavigate }: KedaTriggerAuthRendererProps) {
|
|
14
|
+
const spec = data.spec || {}
|
|
15
|
+
const conditions = data.status?.conditions || []
|
|
16
|
+
|
|
17
|
+
const secretRefs = getTriggerAuthSecretRefs(data)
|
|
18
|
+
const envVars = getTriggerAuthEnvVars(data)
|
|
19
|
+
const vault = spec.hashiCorpVault
|
|
20
|
+
const azureKeyVault = spec.azureKeyVault
|
|
21
|
+
const awsSecretManager = spec.awsSecretManager
|
|
22
|
+
const podIdentity = spec.podIdentity
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
{/* Pod Identity */}
|
|
27
|
+
{podIdentity && (
|
|
28
|
+
<Section title="Pod Identity" icon={Shield}>
|
|
29
|
+
<PropertyList>
|
|
30
|
+
<Property label="Provider" value={podIdentity.provider || '-'} />
|
|
31
|
+
{podIdentity.identityId && (
|
|
32
|
+
<Property label="Identity ID" value={podIdentity.identityId} />
|
|
33
|
+
)}
|
|
34
|
+
{podIdentity.identityOwner && (
|
|
35
|
+
<Property label="Identity Owner" value={podIdentity.identityOwner} />
|
|
36
|
+
)}
|
|
37
|
+
</PropertyList>
|
|
38
|
+
</Section>
|
|
39
|
+
)}
|
|
40
|
+
|
|
41
|
+
{/* Secret References */}
|
|
42
|
+
{secretRefs.length > 0 && (
|
|
43
|
+
<Section title={`Secret References (${secretRefs.length})`} icon={KeyRound} defaultExpanded>
|
|
44
|
+
<div className="space-y-2">
|
|
45
|
+
{secretRefs.map((ref, i) => (
|
|
46
|
+
<div key={i} className="bg-theme-elevated/30 rounded p-2">
|
|
47
|
+
<div className="flex flex-wrap gap-x-4 gap-y-1 text-sm">
|
|
48
|
+
<span className="text-theme-text-primary font-medium">{ref.parameter}</span>
|
|
49
|
+
<span className="text-theme-text-secondary">
|
|
50
|
+
Secret: <ResourceLink name={ref.name} kind="secrets" namespace={data.metadata?.namespace || ''} onNavigate={onNavigate} /> / {ref.key}
|
|
51
|
+
</span>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
))}
|
|
55
|
+
</div>
|
|
56
|
+
</Section>
|
|
57
|
+
)}
|
|
58
|
+
|
|
59
|
+
{/* Environment Variables */}
|
|
60
|
+
{envVars.length > 0 && (
|
|
61
|
+
<Section title={`Environment Variables (${envVars.length})`} defaultExpanded>
|
|
62
|
+
<div className="space-y-2">
|
|
63
|
+
{envVars.map((env, i) => (
|
|
64
|
+
<div key={i} className="bg-theme-elevated/30 rounded p-2">
|
|
65
|
+
<div className="flex flex-wrap gap-x-4 gap-y-1 text-sm">
|
|
66
|
+
<span className="text-theme-text-primary font-medium">{env.parameter}</span>
|
|
67
|
+
<span className="text-theme-text-secondary">Env: {env.name}</span>
|
|
68
|
+
{env.containerName && (
|
|
69
|
+
<span className="text-theme-text-tertiary">Container: {env.containerName}</span>
|
|
70
|
+
)}
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
))}
|
|
74
|
+
</div>
|
|
75
|
+
</Section>
|
|
76
|
+
)}
|
|
77
|
+
|
|
78
|
+
{/* HashiCorp Vault */}
|
|
79
|
+
{vault && (
|
|
80
|
+
<Section title="HashiCorp Vault" icon={Server}>
|
|
81
|
+
<PropertyList>
|
|
82
|
+
<Property label="Address" value={vault.address || '-'} />
|
|
83
|
+
{vault.authentication && (
|
|
84
|
+
<Property label="Authentication" value={vault.authentication} />
|
|
85
|
+
)}
|
|
86
|
+
{vault.role && <Property label="Role" value={vault.role} />}
|
|
87
|
+
{vault.mount && <Property label="Mount" value={vault.mount} />}
|
|
88
|
+
</PropertyList>
|
|
89
|
+
{vault.secrets && vault.secrets.length > 0 && (
|
|
90
|
+
<div className="mt-2 space-y-1">
|
|
91
|
+
<div className="text-xs font-medium text-theme-text-secondary uppercase tracking-wider mb-1">Secrets</div>
|
|
92
|
+
{vault.secrets.map((s: any, i: number) => (
|
|
93
|
+
<div key={i} className="bg-theme-elevated/30 rounded p-2 text-sm">
|
|
94
|
+
<span className="text-theme-text-primary font-medium">{s.parameter}</span>
|
|
95
|
+
<span className="text-theme-text-secondary ml-2">{s.path} / {s.key}</span>
|
|
96
|
+
</div>
|
|
97
|
+
))}
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
</Section>
|
|
101
|
+
)}
|
|
102
|
+
|
|
103
|
+
{/* Azure Key Vault */}
|
|
104
|
+
{azureKeyVault && (
|
|
105
|
+
<Section title="Azure Key Vault" icon={Cloud}>
|
|
106
|
+
<PropertyList>
|
|
107
|
+
<Property label="Vault URI" value={azureKeyVault.vaultUri || '-'} />
|
|
108
|
+
{azureKeyVault.credentials?.clientId && (
|
|
109
|
+
<Property label="Client ID" value={azureKeyVault.credentials.clientId} />
|
|
110
|
+
)}
|
|
111
|
+
</PropertyList>
|
|
112
|
+
{azureKeyVault.secrets && azureKeyVault.secrets.length > 0 && (
|
|
113
|
+
<div className="mt-2 space-y-1">
|
|
114
|
+
<div className="text-xs font-medium text-theme-text-secondary uppercase tracking-wider mb-1">Secrets</div>
|
|
115
|
+
{azureKeyVault.secrets.map((s: any, i: number) => (
|
|
116
|
+
<div key={i} className="bg-theme-elevated/30 rounded p-2 text-sm">
|
|
117
|
+
<span className="text-theme-text-primary font-medium">{s.parameter}</span>
|
|
118
|
+
<span className="text-theme-text-secondary ml-2">{s.name}</span>
|
|
119
|
+
</div>
|
|
120
|
+
))}
|
|
121
|
+
</div>
|
|
122
|
+
)}
|
|
123
|
+
</Section>
|
|
124
|
+
)}
|
|
125
|
+
|
|
126
|
+
{/* AWS Secrets Manager */}
|
|
127
|
+
{awsSecretManager && (
|
|
128
|
+
<Section title="AWS Secrets Manager" icon={Cloud}>
|
|
129
|
+
<PropertyList>
|
|
130
|
+
{awsSecretManager.region && (
|
|
131
|
+
<Property label="Region" value={awsSecretManager.region} />
|
|
132
|
+
)}
|
|
133
|
+
</PropertyList>
|
|
134
|
+
{awsSecretManager.secrets && awsSecretManager.secrets.length > 0 && (
|
|
135
|
+
<div className="mt-2 space-y-1">
|
|
136
|
+
<div className="text-xs font-medium text-theme-text-secondary uppercase tracking-wider mb-1">Secrets</div>
|
|
137
|
+
{awsSecretManager.secrets.map((s: any, i: number) => (
|
|
138
|
+
<div key={i} className="bg-theme-elevated/30 rounded p-2 text-sm">
|
|
139
|
+
<span className="text-theme-text-primary font-medium">{s.parameter}</span>
|
|
140
|
+
<span className="text-theme-text-secondary ml-2">{s.name}</span>
|
|
141
|
+
</div>
|
|
142
|
+
))}
|
|
143
|
+
</div>
|
|
144
|
+
)}
|
|
145
|
+
</Section>
|
|
146
|
+
)}
|
|
147
|
+
|
|
148
|
+
{conditions.length > 0 && <ConditionsSection conditions={conditions} />}
|
|
149
|
+
</>
|
|
150
|
+
)
|
|
151
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Settings, Container } from 'lucide-react'
|
|
2
|
+
import { clsx } from 'clsx'
|
|
3
|
+
import { Section, PropertyList, Property, ConditionsSection, KnativeNotReadyBanner, ResourceLink } from '../../ui/drawer-components'
|
|
4
|
+
import { getKnativeConditionStatus } from '../resource-utils-knative'
|
|
5
|
+
|
|
6
|
+
interface KnativeConfigurationRendererProps {
|
|
7
|
+
data: any
|
|
8
|
+
onNavigate?: (ref: { kind: string; namespace: string; name: string }) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function KnativeConfigurationRenderer({ data, onNavigate }: KnativeConfigurationRendererProps) {
|
|
12
|
+
const status = getKnativeConditionStatus(data)
|
|
13
|
+
const ns = data.metadata?.namespace || ''
|
|
14
|
+
|
|
15
|
+
const latestCreated = data.status?.latestCreatedRevisionName
|
|
16
|
+
const latestReady = data.status?.latestReadyRevisionName
|
|
17
|
+
const containers = data.spec?.template?.spec?.containers || []
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<>
|
|
21
|
+
<KnativeNotReadyBanner status={status} data={data} resourceType="Configuration" />
|
|
22
|
+
|
|
23
|
+
<Section title="Overview" icon={Settings} defaultExpanded>
|
|
24
|
+
<PropertyList>
|
|
25
|
+
<Property label="Status" value={
|
|
26
|
+
<span className={clsx('px-2 py-0.5 rounded text-xs font-medium', status.color)}>
|
|
27
|
+
{status.text}
|
|
28
|
+
</span>
|
|
29
|
+
} />
|
|
30
|
+
<Property label="Latest Created" value={latestCreated ? (
|
|
31
|
+
<ResourceLink
|
|
32
|
+
name={latestCreated}
|
|
33
|
+
kind="revisions"
|
|
34
|
+
namespace={ns}
|
|
35
|
+
onNavigate={onNavigate}
|
|
36
|
+
/>
|
|
37
|
+
) : '-'} />
|
|
38
|
+
<Property label="Latest Ready" value={latestReady ? (
|
|
39
|
+
<ResourceLink
|
|
40
|
+
name={latestReady}
|
|
41
|
+
kind="revisions"
|
|
42
|
+
namespace={ns}
|
|
43
|
+
onNavigate={onNavigate}
|
|
44
|
+
/>
|
|
45
|
+
) : '-'} />
|
|
46
|
+
</PropertyList>
|
|
47
|
+
</Section>
|
|
48
|
+
|
|
49
|
+
{containers.length > 0 && (
|
|
50
|
+
<Section title="Template" icon={Container} defaultExpanded>
|
|
51
|
+
<div className="space-y-2">
|
|
52
|
+
{containers.map((c: any, i: number) => (
|
|
53
|
+
<div key={i} className="bg-theme-elevated/30 rounded p-2 text-sm">
|
|
54
|
+
<div className="font-medium text-theme-text-primary">{c.name || 'container'}</div>
|
|
55
|
+
<div className="text-xs text-theme-text-secondary truncate" title={c.image}>{c.image}</div>
|
|
56
|
+
{c.ports && c.ports.length > 0 && (
|
|
57
|
+
<div className="text-xs text-theme-text-tertiary mt-1">
|
|
58
|
+
Ports: {c.ports.map((p: any) => `${p.containerPort}/${p.protocol || 'TCP'}`).join(', ')}
|
|
59
|
+
</div>
|
|
60
|
+
)}
|
|
61
|
+
</div>
|
|
62
|
+
))}
|
|
63
|
+
</div>
|
|
64
|
+
</Section>
|
|
65
|
+
)}
|
|
66
|
+
|
|
67
|
+
<ConditionsSection conditions={data.status?.conditions || []} />
|
|
68
|
+
</>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { Radio, Filter, FileType, Inbox, ArrowRightLeft } from 'lucide-react'
|
|
2
|
+
import { clsx } from 'clsx'
|
|
3
|
+
import { Section, PropertyList, Property, ConditionsSection, KnativeNotReadyBanner, ResourceLink } from '../../ui/drawer-components'
|
|
4
|
+
import { getKnativeConditionStatus } from '../resource-utils-knative'
|
|
5
|
+
|
|
6
|
+
interface RendererProps {
|
|
7
|
+
data: any
|
|
8
|
+
onNavigate?: (ref: { kind: string; namespace: string; name: string }) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Broker
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
export function BrokerRenderer({ data, onNavigate }: RendererProps) {
|
|
16
|
+
const status = getKnativeConditionStatus(data)
|
|
17
|
+
const ns = data.metadata?.namespace || ''
|
|
18
|
+
const address = data.status?.address?.url
|
|
19
|
+
const delivery = data.spec?.delivery
|
|
20
|
+
const brokerClass = data.metadata?.annotations?.['eventing.knative.dev/broker.class']
|
|
21
|
+
const configRef = data.spec?.config
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<KnativeNotReadyBanner status={status} data={data} resourceType="Broker" />
|
|
26
|
+
|
|
27
|
+
<Section title="Overview" icon={Radio} defaultExpanded>
|
|
28
|
+
<PropertyList>
|
|
29
|
+
<Property label="Status" value={
|
|
30
|
+
<span className={clsx('px-2 py-0.5 rounded text-xs font-medium', status.color)}>
|
|
31
|
+
{status.text}
|
|
32
|
+
</span>
|
|
33
|
+
} />
|
|
34
|
+
<Property label="Address" value={address ? (
|
|
35
|
+
<span className="text-theme-text-primary break-all">{address}</span>
|
|
36
|
+
) : undefined} />
|
|
37
|
+
<Property label="Class" value={brokerClass} />
|
|
38
|
+
{configRef && (
|
|
39
|
+
<Property label="Config" value={`${configRef.kind}/${configRef.name}`} />
|
|
40
|
+
)}
|
|
41
|
+
</PropertyList>
|
|
42
|
+
</Section>
|
|
43
|
+
|
|
44
|
+
{delivery && (
|
|
45
|
+
<Section title="Delivery" defaultExpanded>
|
|
46
|
+
<PropertyList>
|
|
47
|
+
{delivery.deadLetterSink?.ref && (
|
|
48
|
+
<Property label="Dead Letter" value={
|
|
49
|
+
<ResourceLink
|
|
50
|
+
name={delivery.deadLetterSink.ref.name}
|
|
51
|
+
kind={delivery.deadLetterSink.ref.kind?.toLowerCase() + 's'}
|
|
52
|
+
namespace={delivery.deadLetterSink.ref.namespace || ns}
|
|
53
|
+
onNavigate={onNavigate}
|
|
54
|
+
/>
|
|
55
|
+
} />
|
|
56
|
+
)}
|
|
57
|
+
{delivery.deadLetterSink?.uri && (
|
|
58
|
+
<Property label="Dead Letter URI" value={delivery.deadLetterSink.uri} />
|
|
59
|
+
)}
|
|
60
|
+
<Property label="Retry" value={delivery.retry != null ? String(delivery.retry) : undefined} />
|
|
61
|
+
<Property label="Backoff Policy" value={delivery.backoffPolicy} />
|
|
62
|
+
<Property label="Backoff Delay" value={delivery.backoffDelay} />
|
|
63
|
+
</PropertyList>
|
|
64
|
+
</Section>
|
|
65
|
+
)}
|
|
66
|
+
|
|
67
|
+
<ConditionsSection conditions={data.status?.conditions || []} />
|
|
68
|
+
</>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// Trigger
|
|
74
|
+
// ============================================================================
|
|
75
|
+
|
|
76
|
+
export function TriggerRenderer({ data, onNavigate }: RendererProps) {
|
|
77
|
+
const status = getKnativeConditionStatus(data)
|
|
78
|
+
const ns = data.metadata?.namespace || ''
|
|
79
|
+
const spec = data.spec || {}
|
|
80
|
+
const brokerName = spec.broker || 'default'
|
|
81
|
+
const subscriberRef = spec.subscriber?.ref
|
|
82
|
+
const subscriberUri = spec.subscriber?.uri
|
|
83
|
+
const filterAttrs = spec.filter?.attributes || {}
|
|
84
|
+
const filterEntries = Object.entries(filterAttrs)
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<>
|
|
88
|
+
<KnativeNotReadyBanner status={status} data={data} resourceType="Trigger" />
|
|
89
|
+
|
|
90
|
+
<Section title="Overview" icon={Filter} defaultExpanded>
|
|
91
|
+
<PropertyList>
|
|
92
|
+
<Property label="Status" value={
|
|
93
|
+
<span className={clsx('px-2 py-0.5 rounded text-xs font-medium', status.color)}>
|
|
94
|
+
{status.text}
|
|
95
|
+
</span>
|
|
96
|
+
} />
|
|
97
|
+
<Property label="Broker" value={
|
|
98
|
+
<ResourceLink
|
|
99
|
+
name={brokerName}
|
|
100
|
+
kind="brokers"
|
|
101
|
+
namespace={ns}
|
|
102
|
+
onNavigate={onNavigate}
|
|
103
|
+
/>
|
|
104
|
+
} />
|
|
105
|
+
<Property label="Subscriber" value={
|
|
106
|
+
subscriberRef ? (
|
|
107
|
+
<ResourceLink
|
|
108
|
+
name={subscriberRef.name}
|
|
109
|
+
kind={(subscriberRef.kind?.toLowerCase() || 'services') + (subscriberRef.kind?.toLowerCase().endsWith('s') ? '' : 's')}
|
|
110
|
+
namespace={subscriberRef.namespace || ns}
|
|
111
|
+
onNavigate={onNavigate}
|
|
112
|
+
/>
|
|
113
|
+
) : subscriberUri ? (
|
|
114
|
+
<span className="text-theme-text-primary break-all">{subscriberUri}</span>
|
|
115
|
+
) : '-'
|
|
116
|
+
} />
|
|
117
|
+
</PropertyList>
|
|
118
|
+
</Section>
|
|
119
|
+
|
|
120
|
+
{filterEntries.length > 0 && (
|
|
121
|
+
<Section title={`Filter (${filterEntries.length} attributes)`} defaultExpanded>
|
|
122
|
+
<div className="flex flex-wrap gap-1">
|
|
123
|
+
{filterEntries.map(([key, val]) => (
|
|
124
|
+
<span key={key} className="px-2 py-0.5 bg-theme-elevated rounded text-xs text-theme-text-secondary">
|
|
125
|
+
{key}={String(val)}
|
|
126
|
+
</span>
|
|
127
|
+
))}
|
|
128
|
+
</div>
|
|
129
|
+
</Section>
|
|
130
|
+
)}
|
|
131
|
+
|
|
132
|
+
<ConditionsSection conditions={data.status?.conditions || []} />
|
|
133
|
+
</>
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ============================================================================
|
|
138
|
+
// EventType
|
|
139
|
+
// ============================================================================
|
|
140
|
+
|
|
141
|
+
export function EventTypeRenderer({ data }: RendererProps) {
|
|
142
|
+
const spec = data.spec || {}
|
|
143
|
+
const status = data.status || {}
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<>
|
|
147
|
+
<Section title="Overview" icon={FileType} defaultExpanded>
|
|
148
|
+
<PropertyList>
|
|
149
|
+
<Property label="Type" value={spec.type} />
|
|
150
|
+
<Property label="Source" value={spec.source} />
|
|
151
|
+
<Property label="Schema" value={spec.schema} />
|
|
152
|
+
<Property label="Description" value={spec.description} />
|
|
153
|
+
<Property label="Broker" value={spec.reference?.name || spec.broker} />
|
|
154
|
+
</PropertyList>
|
|
155
|
+
</Section>
|
|
156
|
+
|
|
157
|
+
<ConditionsSection conditions={status.conditions || []} />
|
|
158
|
+
</>
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ============================================================================
|
|
163
|
+
// Channel
|
|
164
|
+
// ============================================================================
|
|
165
|
+
|
|
166
|
+
export function ChannelRenderer({ data }: RendererProps) {
|
|
167
|
+
const status = getKnativeConditionStatus(data)
|
|
168
|
+
const address = data.status?.address?.url
|
|
169
|
+
const subscribers = data.status?.subscribers || []
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<>
|
|
173
|
+
<KnativeNotReadyBanner status={status} data={data} resourceType="Channel" />
|
|
174
|
+
|
|
175
|
+
<Section title="Overview" icon={Inbox} defaultExpanded>
|
|
176
|
+
<PropertyList>
|
|
177
|
+
<Property label="Status" value={
|
|
178
|
+
<span className={clsx('px-2 py-0.5 rounded text-xs font-medium', status.color)}>
|
|
179
|
+
{status.text}
|
|
180
|
+
</span>
|
|
181
|
+
} />
|
|
182
|
+
<Property label="Address" value={address ? (
|
|
183
|
+
<span className="text-theme-text-primary break-all">{address}</span>
|
|
184
|
+
) : undefined} />
|
|
185
|
+
</PropertyList>
|
|
186
|
+
</Section>
|
|
187
|
+
|
|
188
|
+
{subscribers.length > 0 && (
|
|
189
|
+
<Section title={`Subscribers (${subscribers.length})`} defaultExpanded>
|
|
190
|
+
<div className="space-y-1.5">
|
|
191
|
+
{subscribers.map((sub: any, i: number) => (
|
|
192
|
+
<div key={i} className="text-sm text-theme-text-secondary">
|
|
193
|
+
{sub.subscriberURI || sub.replyURI || `Subscriber ${i + 1}`}
|
|
194
|
+
{sub.ready === 'True' && (
|
|
195
|
+
<span className="ml-2 px-1.5 py-0.5 bg-green-500/20 text-green-400 rounded text-[10px]">ready</span>
|
|
196
|
+
)}
|
|
197
|
+
{sub.ready === 'False' && (
|
|
198
|
+
<span className="ml-2 px-1.5 py-0.5 bg-red-500/20 text-red-400 rounded text-[10px]">not ready</span>
|
|
199
|
+
)}
|
|
200
|
+
</div>
|
|
201
|
+
))}
|
|
202
|
+
</div>
|
|
203
|
+
</Section>
|
|
204
|
+
)}
|
|
205
|
+
|
|
206
|
+
<ConditionsSection conditions={data.status?.conditions || []} />
|
|
207
|
+
</>
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ============================================================================
|
|
212
|
+
// InMemoryChannel
|
|
213
|
+
// ============================================================================
|
|
214
|
+
|
|
215
|
+
export function InMemoryChannelRenderer({ data, onNavigate }: RendererProps) {
|
|
216
|
+
// InMemoryChannel has the same shape as Channel
|
|
217
|
+
return <ChannelRenderer data={data} onNavigate={onNavigate} />
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ============================================================================
|
|
221
|
+
// Subscription
|
|
222
|
+
// ============================================================================
|
|
223
|
+
|
|
224
|
+
export function SubscriptionRenderer({ data, onNavigate }: RendererProps) {
|
|
225
|
+
const status = getKnativeConditionStatus(data)
|
|
226
|
+
const ns = data.metadata?.namespace || ''
|
|
227
|
+
const spec = data.spec || {}
|
|
228
|
+
|
|
229
|
+
const channelRef = spec.channel
|
|
230
|
+
const subscriberRef = spec.subscriber?.ref
|
|
231
|
+
const subscriberUri = spec.subscriber?.uri
|
|
232
|
+
const replyRef = spec.reply?.ref
|
|
233
|
+
const replyUri = spec.reply?.uri
|
|
234
|
+
const delivery = spec.delivery
|
|
235
|
+
|
|
236
|
+
return (
|
|
237
|
+
<>
|
|
238
|
+
<KnativeNotReadyBanner status={status} data={data} resourceType="Subscription" />
|
|
239
|
+
|
|
240
|
+
<Section title="Overview" icon={ArrowRightLeft} defaultExpanded>
|
|
241
|
+
<PropertyList>
|
|
242
|
+
<Property label="Status" value={
|
|
243
|
+
<span className={clsx('px-2 py-0.5 rounded text-xs font-medium', status.color)}>
|
|
244
|
+
{status.text}
|
|
245
|
+
</span>
|
|
246
|
+
} />
|
|
247
|
+
{channelRef && (
|
|
248
|
+
<Property label="Channel" value={
|
|
249
|
+
<ResourceLink
|
|
250
|
+
name={channelRef.name}
|
|
251
|
+
kind={(channelRef.kind?.toLowerCase() || 'channels') + (channelRef.kind?.toLowerCase().endsWith('s') ? '' : 's')}
|
|
252
|
+
namespace={ns}
|
|
253
|
+
onNavigate={onNavigate}
|
|
254
|
+
/>
|
|
255
|
+
} />
|
|
256
|
+
)}
|
|
257
|
+
<Property label="Subscriber" value={
|
|
258
|
+
subscriberRef ? (
|
|
259
|
+
<ResourceLink
|
|
260
|
+
name={subscriberRef.name}
|
|
261
|
+
kind={(subscriberRef.kind?.toLowerCase() || 'services') + (subscriberRef.kind?.toLowerCase().endsWith('s') ? '' : 's')}
|
|
262
|
+
namespace={subscriberRef.namespace || ns}
|
|
263
|
+
onNavigate={onNavigate}
|
|
264
|
+
/>
|
|
265
|
+
) : subscriberUri ? (
|
|
266
|
+
<span className="text-theme-text-primary break-all">{subscriberUri}</span>
|
|
267
|
+
) : '-'
|
|
268
|
+
} />
|
|
269
|
+
<Property label="Reply" value={
|
|
270
|
+
replyRef ? (
|
|
271
|
+
<ResourceLink
|
|
272
|
+
name={replyRef.name}
|
|
273
|
+
kind={(replyRef.kind?.toLowerCase() || 'channels') + (replyRef.kind?.toLowerCase().endsWith('s') ? '' : 's')}
|
|
274
|
+
namespace={replyRef.namespace || ns}
|
|
275
|
+
onNavigate={onNavigate}
|
|
276
|
+
/>
|
|
277
|
+
) : replyUri ? (
|
|
278
|
+
<span className="text-theme-text-primary break-all">{replyUri}</span>
|
|
279
|
+
) : undefined
|
|
280
|
+
} />
|
|
281
|
+
</PropertyList>
|
|
282
|
+
</Section>
|
|
283
|
+
|
|
284
|
+
{delivery?.deadLetterSink && (
|
|
285
|
+
<Section title="Dead Letter" defaultExpanded>
|
|
286
|
+
<PropertyList>
|
|
287
|
+
{delivery.deadLetterSink.ref && (
|
|
288
|
+
<Property label="Sink" value={
|
|
289
|
+
<ResourceLink
|
|
290
|
+
name={delivery.deadLetterSink.ref.name}
|
|
291
|
+
kind={(delivery.deadLetterSink.ref.kind?.toLowerCase() || 'services') + 's'}
|
|
292
|
+
namespace={delivery.deadLetterSink.ref.namespace || ns}
|
|
293
|
+
onNavigate={onNavigate}
|
|
294
|
+
/>
|
|
295
|
+
} />
|
|
296
|
+
)}
|
|
297
|
+
{delivery.deadLetterSink.uri && (
|
|
298
|
+
<Property label="URI" value={delivery.deadLetterSink.uri} />
|
|
299
|
+
)}
|
|
300
|
+
<Property label="Retry" value={delivery.retry != null ? String(delivery.retry) : undefined} />
|
|
301
|
+
<Property label="Backoff Policy" value={delivery.backoffPolicy} />
|
|
302
|
+
</PropertyList>
|
|
303
|
+
</Section>
|
|
304
|
+
)}
|
|
305
|
+
|
|
306
|
+
<ConditionsSection conditions={data.status?.conditions || []} />
|
|
307
|
+
</>
|
|
308
|
+
)
|
|
309
|
+
}
|