@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.
Files changed (193) hide show
  1. package/package.json +63 -0
  2. package/src/components/dock/BottomDock.tsx +204 -0
  3. package/src/components/dock/DockContext.tsx +212 -0
  4. package/src/components/dock/TerminalTab.tsx +333 -0
  5. package/src/components/dock/index.ts +3 -0
  6. package/src/components/gitops/GitOpsActions.tsx +227 -0
  7. package/src/components/gitops/GitOpsStatusBadge.tsx +221 -0
  8. package/src/components/gitops/ManagedResourcesList.tsx +210 -0
  9. package/src/components/gitops/SyncCountdown.tsx +146 -0
  10. package/src/components/gitops/index.ts +4 -0
  11. package/src/components/logs/JsonLogLine.tsx +90 -0
  12. package/src/components/logs/LogCore.tsx +553 -0
  13. package/src/components/logs/LogToolbarSelects.tsx +74 -0
  14. package/src/components/logs/LogsViewer.tsx +146 -0
  15. package/src/components/logs/WorkloadLogsViewer.tsx +263 -0
  16. package/src/components/logs/index.ts +13 -0
  17. package/src/components/logs/useLogBuffer.ts +138 -0
  18. package/src/components/logs/useLogSearch.ts +151 -0
  19. package/src/components/logs/useLogStream.ts +61 -0
  20. package/src/components/resources/ResourcesView.tsx +5494 -0
  21. package/src/components/resources/index.ts +17 -0
  22. package/src/components/resources/renderers/AlertRenderer.tsx +166 -0
  23. package/src/components/resources/renderers/ArgoApplicationRenderer.tsx +233 -0
  24. package/src/components/resources/renderers/CNPGBackupRenderer.tsx +89 -0
  25. package/src/components/resources/renderers/CNPGClusterRenderer.tsx +194 -0
  26. package/src/components/resources/renderers/CNPGPoolerRenderer.tsx +79 -0
  27. package/src/components/resources/renderers/CNPGScheduledBackupRenderer.tsx +68 -0
  28. package/src/components/resources/renderers/CertificateRenderer.tsx +209 -0
  29. package/src/components/resources/renderers/CertificateRequestRenderer.tsx +123 -0
  30. package/src/components/resources/renderers/ChallengeRenderer.tsx +111 -0
  31. package/src/components/resources/renderers/ClusterComplianceReportRenderer.tsx +164 -0
  32. package/src/components/resources/renderers/ClusterExternalSecretRenderer.tsx +140 -0
  33. package/src/components/resources/renderers/ClusterIssuerRenderer.tsx +153 -0
  34. package/src/components/resources/renderers/ConfigAuditReportRenderer.tsx +221 -0
  35. package/src/components/resources/renderers/ConfigMapRenderer.tsx +124 -0
  36. package/src/components/resources/renderers/CronJobRenderer.tsx +86 -0
  37. package/src/components/resources/renderers/EventRenderer.tsx +175 -0
  38. package/src/components/resources/renderers/ExposedSecretReportRenderer.tsx +119 -0
  39. package/src/components/resources/renderers/ExternalSecretRenderer.tsx +172 -0
  40. package/src/components/resources/renderers/FluxHelmReleaseRenderer.tsx +242 -0
  41. package/src/components/resources/renderers/GRPCRouteRenderer.tsx +263 -0
  42. package/src/components/resources/renderers/GatewayClassRenderer.tsx +68 -0
  43. package/src/components/resources/renderers/GatewayRenderer.tsx +218 -0
  44. package/src/components/resources/renderers/GenericRenderer.tsx +476 -0
  45. package/src/components/resources/renderers/GitRepositoryRenderer.tsx +154 -0
  46. package/src/components/resources/renderers/HPARenderer.tsx +164 -0
  47. package/src/components/resources/renderers/HTTPRouteRenderer.tsx +303 -0
  48. package/src/components/resources/renderers/HelmRepositoryRenderer.tsx +167 -0
  49. package/src/components/resources/renderers/IngressClassRenderer.tsx +49 -0
  50. package/src/components/resources/renderers/IngressRenderer.tsx +104 -0
  51. package/src/components/resources/renderers/IstioAuthorizationPolicyRenderer.tsx +175 -0
  52. package/src/components/resources/renderers/IstioDestinationRuleRenderer.tsx +176 -0
  53. package/src/components/resources/renderers/IstioGatewayRenderer.tsx +125 -0
  54. package/src/components/resources/renderers/IstioPeerAuthenticationRenderer.tsx +84 -0
  55. package/src/components/resources/renderers/IstioServiceEntryRenderer.tsx +112 -0
  56. package/src/components/resources/renderers/IstioVirtualServiceRenderer.tsx +288 -0
  57. package/src/components/resources/renderers/JobRenderer.tsx +103 -0
  58. package/src/components/resources/renderers/KarpenterEC2NodeClassRenderer.tsx +157 -0
  59. package/src/components/resources/renderers/KarpenterNodeClaimRenderer.tsx +188 -0
  60. package/src/components/resources/renderers/KarpenterNodePoolRenderer.tsx +148 -0
  61. package/src/components/resources/renderers/KedaScaledJobRenderer.tsx +90 -0
  62. package/src/components/resources/renderers/KedaScaledObjectRenderer.tsx +136 -0
  63. package/src/components/resources/renderers/KedaTriggerAuthRenderer.tsx +151 -0
  64. package/src/components/resources/renderers/KnativeConfigurationRenderer.tsx +70 -0
  65. package/src/components/resources/renderers/KnativeEventingRenderer.tsx +309 -0
  66. package/src/components/resources/renderers/KnativeFlowRenderer.tsx +142 -0
  67. package/src/components/resources/renderers/KnativeNetworkingRenderer.tsx +232 -0
  68. package/src/components/resources/renderers/KnativeRevisionRenderer.tsx +97 -0
  69. package/src/components/resources/renderers/KnativeRouteRenderer.tsx +74 -0
  70. package/src/components/resources/renderers/KnativeServiceRenderer.tsx +138 -0
  71. package/src/components/resources/renderers/KnativeSourceRenderer.tsx +220 -0
  72. package/src/components/resources/renderers/KustomizationRenderer.tsx +151 -0
  73. package/src/components/resources/renderers/KyvernoPolicyReportRenderer.tsx +352 -0
  74. package/src/components/resources/renderers/LeaseRenderer.tsx +93 -0
  75. package/src/components/resources/renderers/NetworkPolicyRenderer.tsx +208 -0
  76. package/src/components/resources/renderers/NodeRenderer.tsx +282 -0
  77. package/src/components/resources/renderers/OCIRepositoryRenderer.tsx +153 -0
  78. package/src/components/resources/renderers/OrderRenderer.tsx +108 -0
  79. package/src/components/resources/renderers/PVCRenderer.tsx +98 -0
  80. package/src/components/resources/renderers/PersistentVolumeRenderer.tsx +138 -0
  81. package/src/components/resources/renderers/PodDisruptionBudgetRenderer.tsx +126 -0
  82. package/src/components/resources/renderers/PodMonitorRenderer.tsx +63 -0
  83. package/src/components/resources/renderers/PodRenderer.tsx +677 -0
  84. package/src/components/resources/renderers/PriorityClassRenderer.tsx +50 -0
  85. package/src/components/resources/renderers/PrometheusRuleRenderer.tsx +62 -0
  86. package/src/components/resources/renderers/ReplicaSetRenderer.tsx +71 -0
  87. package/src/components/resources/renderers/RoleBindingRenderer.tsx +97 -0
  88. package/src/components/resources/renderers/RoleRenderer.tsx +192 -0
  89. package/src/components/resources/renderers/RolloutRenderer.tsx +227 -0
  90. package/src/components/resources/renderers/RuntimeClassRenderer.tsx +75 -0
  91. package/src/components/resources/renderers/SbomReportRenderer.tsx +98 -0
  92. package/src/components/resources/renderers/SealedSecretRenderer.tsx +121 -0
  93. package/src/components/resources/renderers/SecretRenderer.tsx +321 -0
  94. package/src/components/resources/renderers/SecretStoreRenderer.tsx +111 -0
  95. package/src/components/resources/renderers/ServiceAccountRenderer.tsx +81 -0
  96. package/src/components/resources/renderers/ServiceMonitorRenderer.tsx +65 -0
  97. package/src/components/resources/renderers/ServiceRenderer.tsx +98 -0
  98. package/src/components/resources/renderers/SimpleRouteRenderer.tsx +195 -0
  99. package/src/components/resources/renderers/StorageClassRenderer.tsx +82 -0
  100. package/src/components/resources/renderers/TraefikIngressRouteRenderer.tsx +257 -0
  101. package/src/components/resources/renderers/VPARenderer.tsx +193 -0
  102. package/src/components/resources/renderers/VeleroBSLRenderer.tsx +73 -0
  103. package/src/components/resources/renderers/VeleroBackupRenderer.tsx +193 -0
  104. package/src/components/resources/renderers/VeleroRestoreRenderer.tsx +161 -0
  105. package/src/components/resources/renderers/VeleroScheduleRenderer.tsx +134 -0
  106. package/src/components/resources/renderers/VeleroVSLRenderer.tsx +36 -0
  107. package/src/components/resources/renderers/VulnerabilityReportRenderer.tsx +347 -0
  108. package/src/components/resources/renderers/WebhookConfigRenderer.tsx +156 -0
  109. package/src/components/resources/renderers/WorkflowRenderer.tsx +202 -0
  110. package/src/components/resources/renderers/WorkflowTemplateRenderer.tsx +91 -0
  111. package/src/components/resources/renderers/WorkloadRenderer.tsx +311 -0
  112. package/src/components/resources/renderers/argo-cells.tsx +118 -0
  113. package/src/components/resources/renderers/certmanager-cells.tsx +164 -0
  114. package/src/components/resources/renderers/cnpg-cells.tsx +161 -0
  115. package/src/components/resources/renderers/eso-cells.tsx +115 -0
  116. package/src/components/resources/renderers/flux-cells.tsx +253 -0
  117. package/src/components/resources/renderers/index.ts +105 -0
  118. package/src/components/resources/renderers/istio-cells.tsx +210 -0
  119. package/src/components/resources/renderers/karpenter-cells.tsx +107 -0
  120. package/src/components/resources/renderers/keda-cells.tsx +94 -0
  121. package/src/components/resources/renderers/knative-cells.tsx +396 -0
  122. package/src/components/resources/renderers/kyverno-cells.tsx +85 -0
  123. package/src/components/resources/renderers/prometheus-cells.tsx +74 -0
  124. package/src/components/resources/renderers/traefik-cells.tsx +120 -0
  125. package/src/components/resources/renderers/trivy-cells.tsx +153 -0
  126. package/src/components/resources/renderers/trivy-shared.tsx +67 -0
  127. package/src/components/resources/renderers/velero-cells.tsx +164 -0
  128. package/src/components/resources/resource-utils-argo.ts +155 -0
  129. package/src/components/resources/resource-utils-certmanager.ts +198 -0
  130. package/src/components/resources/resource-utils-cnpg.ts +344 -0
  131. package/src/components/resources/resource-utils-eso.ts +385 -0
  132. package/src/components/resources/resource-utils-flux.ts +186 -0
  133. package/src/components/resources/resource-utils-istio.ts +372 -0
  134. package/src/components/resources/resource-utils-karpenter.ts +150 -0
  135. package/src/components/resources/resource-utils-keda.ts +203 -0
  136. package/src/components/resources/resource-utils-knative.ts +218 -0
  137. package/src/components/resources/resource-utils-kyverno.ts +224 -0
  138. package/src/components/resources/resource-utils-prometheus.ts +159 -0
  139. package/src/components/resources/resource-utils-traefik.ts +180 -0
  140. package/src/components/resources/resource-utils-trivy.ts +146 -0
  141. package/src/components/resources/resource-utils-velero.ts +293 -0
  142. package/src/components/resources/resource-utils.ts +1558 -0
  143. package/src/components/shared/EditableYamlView.tsx +302 -0
  144. package/src/components/shared/ResourceActionsBar.tsx +924 -0
  145. package/src/components/shared/ResourceRendererDispatch.tsx +557 -0
  146. package/src/components/shared/index.ts +3 -0
  147. package/src/components/timeline/index.ts +1 -0
  148. package/src/components/timeline/shared.tsx +614 -0
  149. package/src/components/topology/GroupNode.tsx +198 -0
  150. package/src/components/topology/K8sResourceNode.tsx +440 -0
  151. package/src/components/topology/TopologyControls.tsx +62 -0
  152. package/src/components/topology/TopologyFilterSidebar.tsx +377 -0
  153. package/src/components/topology/TopologyGraph.tsx +748 -0
  154. package/src/components/topology/TopologySearch.tsx +304 -0
  155. package/src/components/topology/index.ts +7 -0
  156. package/src/components/topology/layout.ts +734 -0
  157. package/src/components/topology/layout.worker.ts +272 -0
  158. package/src/components/topology/topology.css +129 -0
  159. package/src/components/ui/CodeViewer.tsx +451 -0
  160. package/src/components/ui/ConfirmDialog.tsx +188 -0
  161. package/src/components/ui/ForceDeleteConfirmDialog.tsx +57 -0
  162. package/src/components/ui/HealthRing.tsx +72 -0
  163. package/src/components/ui/MetricsChart.tsx +259 -0
  164. package/src/components/ui/ResourceBar.tsx +68 -0
  165. package/src/components/ui/Toast.tsx +225 -0
  166. package/src/components/ui/Tooltip.tsx +165 -0
  167. package/src/components/ui/YamlEditor.tsx +280 -0
  168. package/src/components/ui/drawer-components.tsx +792 -0
  169. package/src/components/ui/index.ts +10 -0
  170. package/src/components/workload/ResourceDetailDrawer.tsx +158 -0
  171. package/src/components/workload/WorkloadView.tsx +1109 -0
  172. package/src/components/workload/index.ts +2 -0
  173. package/src/hooks/index.ts +9 -0
  174. package/src/hooks/useAnimatedUnmount.ts +30 -0
  175. package/src/hooks/useKeyboardShortcuts.tsx +336 -0
  176. package/src/hooks/useRefreshAnimation.ts +58 -0
  177. package/src/index.ts +35 -0
  178. package/src/types/core.ts +894 -0
  179. package/src/types/gitops.ts +458 -0
  180. package/src/types/index.ts +2 -0
  181. package/src/utils/animation.ts +40 -0
  182. package/src/utils/api-resources.ts +185 -0
  183. package/src/utils/badge-colors.ts +399 -0
  184. package/src/utils/context-name.ts +72 -0
  185. package/src/utils/download.ts +19 -0
  186. package/src/utils/format.ts +233 -0
  187. package/src/utils/index.ts +10 -0
  188. package/src/utils/log-format.ts +300 -0
  189. package/src/utils/navigation.ts +119 -0
  190. package/src/utils/resource-hierarchy.ts +630 -0
  191. package/src/utils/resource-icons.ts +206 -0
  192. package/src/vite-env.d.ts +1 -0
  193. package/tsconfig.json +24 -0
@@ -0,0 +1,94 @@
1
+ // KEDA cell components for ResourcesView table
2
+
3
+ import { clsx } from 'clsx'
4
+ import {
5
+ getScaledObjectStatus,
6
+ getScaledObjectTarget,
7
+ getScaledObjectReplicas,
8
+ getScaledObjectTriggerTypes,
9
+ getScaledJobStatus,
10
+ getScaledJobTarget,
11
+ getScaledJobStrategy,
12
+ getScaledJobTriggerTypes,
13
+ getTriggerAuthSecretRefCount,
14
+ getTriggerAuthEnvCount,
15
+ getTriggerAuthHasVault,
16
+ } from '../resource-utils-keda'
17
+
18
+ export function ScaledObjectCell({ resource, column }: { resource: any; column: string }) {
19
+ switch (column) {
20
+ case 'status': {
21
+ const status = getScaledObjectStatus(resource)
22
+ return (
23
+ <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
24
+ {status.text}
25
+ </span>
26
+ )
27
+ }
28
+ case 'target': {
29
+ const target = getScaledObjectTarget(resource)
30
+ return <span className="text-sm text-theme-text-secondary">{target}</span>
31
+ }
32
+ case 'replicas': {
33
+ const replicas = getScaledObjectReplicas(resource)
34
+ return <span className="text-sm text-theme-text-secondary">{replicas}</span>
35
+ }
36
+ case 'triggerTypes': {
37
+ const types = getScaledObjectTriggerTypes(resource)
38
+ return <span className="text-sm text-theme-text-secondary truncate block">{types}</span>
39
+ }
40
+ default:
41
+ return <span className="text-sm text-theme-text-tertiary">-</span>
42
+ }
43
+ }
44
+
45
+ export function ScaledJobCell({ resource, column }: { resource: any; column: string }) {
46
+ switch (column) {
47
+ case 'status': {
48
+ const status = getScaledJobStatus(resource)
49
+ return (
50
+ <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
51
+ {status.text}
52
+ </span>
53
+ )
54
+ }
55
+ case 'target': {
56
+ const target = getScaledJobTarget(resource)
57
+ return <span className="text-sm text-theme-text-secondary">{target}</span>
58
+ }
59
+ case 'strategy': {
60
+ const strategy = getScaledJobStrategy(resource)
61
+ return <span className="text-sm text-theme-text-secondary">{strategy}</span>
62
+ }
63
+ case 'triggerTypes': {
64
+ const types = getScaledJobTriggerTypes(resource)
65
+ return <span className="text-sm text-theme-text-secondary truncate block">{types}</span>
66
+ }
67
+ default:
68
+ return <span className="text-sm text-theme-text-tertiary">-</span>
69
+ }
70
+ }
71
+
72
+ export function TriggerAuthenticationCell({ resource, column }: { resource: any; column: string }) {
73
+ switch (column) {
74
+ case 'secretTargetRef': {
75
+ const count = getTriggerAuthSecretRefCount(resource)
76
+ return <span className="text-sm text-theme-text-secondary">{count > 0 ? count : '-'}</span>
77
+ }
78
+ case 'env': {
79
+ const count = getTriggerAuthEnvCount(resource)
80
+ return <span className="text-sm text-theme-text-secondary">{count > 0 ? count : '-'}</span>
81
+ }
82
+ case 'hashiCorpVault': {
83
+ const hasVault = getTriggerAuthHasVault(resource)
84
+ return <span className="text-sm text-theme-text-secondary">{hasVault ? 'Yes' : '-'}</span>
85
+ }
86
+ default:
87
+ return <span className="text-sm text-theme-text-tertiary">-</span>
88
+ }
89
+ }
90
+
91
+ export function ClusterTriggerAuthenticationCell({ resource, column }: { resource: any; column: string }) {
92
+ // Same rendering logic as TriggerAuthentication
93
+ return <TriggerAuthenticationCell resource={resource} column={column} />
94
+ }
@@ -0,0 +1,396 @@
1
+ // KNative cell components for ResourcesView table
2
+
3
+ import { clsx } from 'clsx'
4
+ import {
5
+ getKnativeConditionStatus,
6
+ getKnativeServiceUrl,
7
+ getKnativeServiceLatestRevision,
8
+ getKnativeServiceTraffic,
9
+ getRevisionStatus,
10
+ getRevisionImage,
11
+ getRevisionConcurrency,
12
+ getRouteUrl,
13
+ getRouteTraffic,
14
+ getConfigurationLatestCreated,
15
+ getConfigurationLatestReady,
16
+ getBrokerAddress,
17
+ getTriggerBroker,
18
+ getTriggerSubscriber,
19
+ getTriggerFilter,
20
+ getSourceSink,
21
+ getPingSourceSchedule,
22
+ getPingSourceData,
23
+ getChannelAddress,
24
+ getSubscriptionChannel,
25
+ getSubscriptionSubscriber,
26
+ getSequenceStepCount,
27
+ getParallelBranchCount,
28
+ getDomainMappingUrl,
29
+ getServerlessServiceMode,
30
+ } from '../resource-utils-knative'
31
+
32
+ function StatusCell({ resource, getStatus }: { resource: any; getStatus: (r: any) => { text: string; color: string } }) {
33
+ const status = getStatus(resource)
34
+ return (
35
+ <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
36
+ {status.text}
37
+ </span>
38
+ )
39
+ }
40
+
41
+ function TextCell({ value }: { value: string }) {
42
+ return <span className="text-sm text-theme-text-secondary truncate block">{value}</span>
43
+ }
44
+
45
+ function NumberCell({ value }: { value: number }) {
46
+ return <span className="text-sm text-theme-text-secondary">{value}</span>
47
+ }
48
+
49
+ function DefaultCell() {
50
+ return <span className="text-sm text-theme-text-tertiary">-</span>
51
+ }
52
+
53
+ // ============================================================================
54
+ // KNATIVE SERVICE
55
+ // ============================================================================
56
+
57
+ export function KnativeServiceCell({ resource, column }: { resource: any; column: string }) {
58
+ switch (column) {
59
+ case 'status':
60
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
61
+ case 'url':
62
+ return <TextCell value={getKnativeServiceUrl(resource)} />
63
+ case 'latestRevision':
64
+ return <TextCell value={getKnativeServiceLatestRevision(resource)} />
65
+ case 'traffic':
66
+ return <TextCell value={getKnativeServiceTraffic(resource)} />
67
+ default:
68
+ return <DefaultCell />
69
+ }
70
+ }
71
+
72
+ // ============================================================================
73
+ // REVISION
74
+ // ============================================================================
75
+
76
+ export function RevisionCell({ resource, column }: { resource: any; column: string }) {
77
+ switch (column) {
78
+ case 'status':
79
+ return <StatusCell resource={resource} getStatus={getRevisionStatus} />
80
+ case 'routing': {
81
+ const state = resource?.metadata?.labels?.['serving.knative.dev/routingState'] || ''
82
+ if (state === 'active') return <span className="text-green-400 text-sm">Active</span>
83
+ if (state === 'reserve') return <span className="text-theme-text-tertiary text-sm">Reserve</span>
84
+ return <TextCell value={state || '-'} />
85
+ }
86
+ case 'image':
87
+ return <TextCell value={getRevisionImage(resource)} />
88
+ case 'concurrency':
89
+ return <TextCell value={getRevisionConcurrency(resource)} />
90
+ default:
91
+ return <DefaultCell />
92
+ }
93
+ }
94
+
95
+ // ============================================================================
96
+ // ROUTE
97
+ // ============================================================================
98
+
99
+ export function RouteCell({ resource, column }: { resource: any; column: string }) {
100
+ switch (column) {
101
+ case 'status':
102
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
103
+ case 'url':
104
+ return <TextCell value={getRouteUrl(resource)} />
105
+ case 'traffic':
106
+ return <TextCell value={getRouteTraffic(resource)} />
107
+ default:
108
+ return <DefaultCell />
109
+ }
110
+ }
111
+
112
+ // ============================================================================
113
+ // CONFIGURATION
114
+ // ============================================================================
115
+
116
+ export function ConfigurationCell({ resource, column }: { resource: any; column: string }) {
117
+ switch (column) {
118
+ case 'status':
119
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
120
+ case 'latestCreated':
121
+ return <TextCell value={getConfigurationLatestCreated(resource)} />
122
+ case 'latestReady':
123
+ return <TextCell value={getConfigurationLatestReady(resource)} />
124
+ default:
125
+ return <DefaultCell />
126
+ }
127
+ }
128
+
129
+ // ============================================================================
130
+ // BROKER
131
+ // ============================================================================
132
+
133
+ export function BrokerCell({ resource, column }: { resource: any; column: string }) {
134
+ switch (column) {
135
+ case 'status':
136
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
137
+ case 'address':
138
+ return <TextCell value={getBrokerAddress(resource)} />
139
+ default:
140
+ return <DefaultCell />
141
+ }
142
+ }
143
+
144
+ // ============================================================================
145
+ // TRIGGER
146
+ // ============================================================================
147
+
148
+ export function TriggerCell({ resource, column }: { resource: any; column: string }) {
149
+ switch (column) {
150
+ case 'status':
151
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
152
+ case 'broker':
153
+ return <TextCell value={getTriggerBroker(resource)} />
154
+ case 'subscriber':
155
+ return <TextCell value={getTriggerSubscriber(resource)} />
156
+ case 'filter':
157
+ return <TextCell value={getTriggerFilter(resource)} />
158
+ default:
159
+ return <DefaultCell />
160
+ }
161
+ }
162
+
163
+ // ============================================================================
164
+ // EVENTTYPE
165
+ // ============================================================================
166
+
167
+ export function EventTypeCell({ resource, column }: { resource: any; column: string }) {
168
+ switch (column) {
169
+ case 'type':
170
+ return <TextCell value={resource?.spec?.type || '-'} />
171
+ case 'source':
172
+ return <TextCell value={resource?.spec?.source || '-'} />
173
+ case 'reference': {
174
+ const ref = resource?.spec?.reference
175
+ if (ref) return <TextCell value={`${ref.kind || ''}/${ref.name || ''}`} />
176
+ const broker = resource?.spec?.broker
177
+ if (broker) return <TextCell value={`Broker/${broker}`} />
178
+ return <DefaultCell />
179
+ }
180
+ default:
181
+ return <DefaultCell />
182
+ }
183
+ }
184
+
185
+ // ============================================================================
186
+ // PING SOURCE
187
+ // ============================================================================
188
+
189
+ export function PingSourceCell({ resource, column }: { resource: any; column: string }) {
190
+ switch (column) {
191
+ case 'status':
192
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
193
+ case 'schedule':
194
+ return <TextCell value={getPingSourceSchedule(resource)} />
195
+ case 'sink':
196
+ return <TextCell value={getSourceSink(resource)} />
197
+ case 'data':
198
+ return <TextCell value={getPingSourceData(resource)} />
199
+ default:
200
+ return <DefaultCell />
201
+ }
202
+ }
203
+
204
+ // ============================================================================
205
+ // APISERVERSOURCE / CONTAINERSOURCE (identical columns: status + sink)
206
+ // ============================================================================
207
+
208
+ function SourceCell({ resource, column }: { resource: any; column: string }) {
209
+ switch (column) {
210
+ case 'status':
211
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
212
+ case 'sink':
213
+ return <TextCell value={getSourceSink(resource)} />
214
+ default:
215
+ return <DefaultCell />
216
+ }
217
+ }
218
+
219
+ export { SourceCell as ApiServerSourceCell, SourceCell as ContainerSourceCell }
220
+
221
+ // ============================================================================
222
+ // SINKBINDING
223
+ // ============================================================================
224
+
225
+ export function SinkBindingCell({ resource, column }: { resource: any; column: string }) {
226
+ switch (column) {
227
+ case 'status':
228
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
229
+ case 'sink':
230
+ return <TextCell value={getSourceSink(resource)} />
231
+ case 'subject': {
232
+ const subject = resource?.spec?.subject
233
+ if (!subject) return <TextCell value="-" />
234
+ if (subject.name) return <TextCell value={`${subject.kind || ''}/${subject.name}`} />
235
+ if (subject.selector?.matchLabels) {
236
+ const labels = Object.entries(subject.selector.matchLabels).map(([k, v]) => `${k}=${v}`).join(', ')
237
+ return <TextCell value={`${subject.kind || ''} (${labels})`} />
238
+ }
239
+ return <TextCell value={subject.kind || '-'} />
240
+ }
241
+ default:
242
+ return <DefaultCell />
243
+ }
244
+ }
245
+
246
+ // ============================================================================
247
+ // CHANNEL / INMEMORYCHANNEL (identical columns: status + address)
248
+ // ============================================================================
249
+
250
+ function ChannelCellBase({ resource, column }: { resource: any; column: string }) {
251
+ switch (column) {
252
+ case 'status':
253
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
254
+ case 'address':
255
+ return <TextCell value={getChannelAddress(resource)} />
256
+ default:
257
+ return <DefaultCell />
258
+ }
259
+ }
260
+
261
+ export { ChannelCellBase as ChannelCell, ChannelCellBase as InMemoryChannelCell }
262
+
263
+ // ============================================================================
264
+ // SUBSCRIPTION
265
+ // ============================================================================
266
+
267
+ export function SubscriptionCell({ resource, column }: { resource: any; column: string }) {
268
+ switch (column) {
269
+ case 'status':
270
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
271
+ case 'channel':
272
+ return <TextCell value={getSubscriptionChannel(resource)} />
273
+ case 'subscriber':
274
+ return <TextCell value={getSubscriptionSubscriber(resource)} />
275
+ default:
276
+ return <DefaultCell />
277
+ }
278
+ }
279
+
280
+ // ============================================================================
281
+ // SEQUENCE
282
+ // ============================================================================
283
+
284
+ export function SequenceCell({ resource, column }: { resource: any; column: string }) {
285
+ switch (column) {
286
+ case 'status':
287
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
288
+ case 'steps':
289
+ return <NumberCell value={getSequenceStepCount(resource)} />
290
+ default:
291
+ return <DefaultCell />
292
+ }
293
+ }
294
+
295
+ // ============================================================================
296
+ // PARALLEL
297
+ // ============================================================================
298
+
299
+ export function ParallelCell({ resource, column }: { resource: any; column: string }) {
300
+ switch (column) {
301
+ case 'status':
302
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
303
+ case 'branches':
304
+ return <NumberCell value={getParallelBranchCount(resource)} />
305
+ default:
306
+ return <DefaultCell />
307
+ }
308
+ }
309
+
310
+ // ============================================================================
311
+ // DOMAINMAPPING
312
+ // ============================================================================
313
+
314
+ export function DomainMappingCell({ resource, column }: { resource: any; column: string }) {
315
+ switch (column) {
316
+ case 'status':
317
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
318
+ case 'url':
319
+ return <TextCell value={getDomainMappingUrl(resource)} />
320
+ default:
321
+ return <DefaultCell />
322
+ }
323
+ }
324
+
325
+ // ============================================================================
326
+ // KNATIVE INGRESS
327
+ // ============================================================================
328
+
329
+ export function KnativeIngressCell({ resource, column }: { resource: any; column: string }) {
330
+ switch (column) {
331
+ case 'status':
332
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
333
+ case 'ingressClass': {
334
+ const cls = resource?.metadata?.annotations?.['networking.knative.dev/ingress.class'] || '-'
335
+ // Show just the short name (e.g., "kourier" from "kourier.ingress.networking.knative.dev")
336
+ const short = cls.includes('.') ? cls.split('.')[0] : cls
337
+ return <TextCell value={short} />
338
+ }
339
+ case 'hosts': {
340
+ const rules = resource?.spec?.rules || []
341
+ const allHosts = rules.flatMap((r: any) => r.hosts || [])
342
+ const unique = [...new Set(allHosts)]
343
+ return <TextCell value={unique.length > 0 ? unique.join(', ') : '-'} />
344
+ }
345
+ case 'visibility': {
346
+ const rules = resource?.spec?.rules || []
347
+ const vis = rules[0]?.visibility || '-'
348
+ return <TextCell value={vis} />
349
+ }
350
+ default:
351
+ return <DefaultCell />
352
+ }
353
+ }
354
+
355
+ // ============================================================================
356
+ // KNATIVE CERTIFICATE
357
+ // ============================================================================
358
+
359
+ export function KnativeCertificateCell({ resource, column }: { resource: any; column: string }) {
360
+ switch (column) {
361
+ case 'status':
362
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
363
+ case 'dnsNames': {
364
+ const names = resource?.spec?.dnsNames || []
365
+ return <TextCell value={names.length > 0 ? names.join(', ') : '-'} />
366
+ }
367
+ case 'secretName':
368
+ return <TextCell value={resource?.spec?.secretName || '-'} />
369
+ default:
370
+ return <DefaultCell />
371
+ }
372
+ }
373
+
374
+ // ============================================================================
375
+ // SERVERLESSSERVICE
376
+ // ============================================================================
377
+
378
+ export function ServerlessServiceCell({ resource, column }: { resource: any; column: string }) {
379
+ switch (column) {
380
+ case 'status':
381
+ return <StatusCell resource={resource} getStatus={getKnativeConditionStatus} />
382
+ case 'mode': {
383
+ const mode = getServerlessServiceMode(resource)
384
+ return (
385
+ <span className={clsx(
386
+ 'inline-flex items-center px-2 py-0.5 rounded text-xs font-medium',
387
+ mode === 'Proxy' ? 'bg-yellow-500/20 text-yellow-400' : 'bg-green-500/20 text-green-400'
388
+ )}>
389
+ {mode}
390
+ </span>
391
+ )
392
+ }
393
+ default:
394
+ return <DefaultCell />
395
+ }
396
+ }
@@ -0,0 +1,85 @@
1
+ // Kyverno / Policy Report cell components for ResourcesView table
2
+
3
+ import { clsx } from 'clsx'
4
+ import {
5
+ getPolicyReportStatus,
6
+ getPolicyReportSummary,
7
+ getKyvernoPolicyStatus,
8
+ getKyvernoPolicyAction,
9
+ getKyvernoPolicyRuleCount,
10
+ } from '../resource-utils-kyverno'
11
+
12
+ export function PolicyReportCell({ resource, column }: { resource: any; column: string }) {
13
+ switch (column) {
14
+ case 'status': {
15
+ const status = getPolicyReportStatus(resource)
16
+ return (
17
+ <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
18
+ {status.text}
19
+ </span>
20
+ )
21
+ }
22
+ case 'pass': {
23
+ const summary = getPolicyReportSummary(resource)
24
+ return <span className={clsx('text-sm', summary.pass > 0 ? 'text-green-400' : 'text-theme-text-tertiary')}>{summary.pass}</span>
25
+ }
26
+ case 'fail': {
27
+ const summary = getPolicyReportSummary(resource)
28
+ return <span className={clsx('text-sm', summary.fail > 0 ? 'text-red-400 font-medium' : 'text-theme-text-tertiary')}>{summary.fail}</span>
29
+ }
30
+ case 'warn': {
31
+ const summary = getPolicyReportSummary(resource)
32
+ return <span className={clsx('text-sm', summary.warn > 0 ? 'text-yellow-400' : 'text-theme-text-tertiary')}>{summary.warn}</span>
33
+ }
34
+ case 'error': {
35
+ const summary = getPolicyReportSummary(resource)
36
+ return <span className={clsx('text-sm', summary.error > 0 ? 'text-red-400 font-medium' : 'text-theme-text-tertiary')}>{summary.error}</span>
37
+ }
38
+ case 'skip': {
39
+ const summary = getPolicyReportSummary(resource)
40
+ return <span className={clsx('text-sm', summary.skip > 0 ? 'text-blue-400' : 'text-theme-text-tertiary')}>{summary.skip}</span>
41
+ }
42
+ default:
43
+ return <span className="text-sm text-theme-text-tertiary">-</span>
44
+ }
45
+ }
46
+
47
+ export function ClusterPolicyReportCell({ resource, column }: { resource: any; column: string }) {
48
+ // Same rendering logic as PolicyReport
49
+ return <PolicyReportCell resource={resource} column={column} />
50
+ }
51
+
52
+ export function KyvernoPolicyCell({ resource, column }: { resource: any; column: string }) {
53
+ switch (column) {
54
+ case 'status': {
55
+ const status = getKyvernoPolicyStatus(resource)
56
+ return (
57
+ <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
58
+ {status.text}
59
+ </span>
60
+ )
61
+ }
62
+ case 'action': {
63
+ const action = getKyvernoPolicyAction(resource)
64
+ return (
65
+ <span className={clsx(
66
+ 'inline-flex items-center px-2 py-0.5 rounded text-xs font-medium',
67
+ action === 'Enforce' ? 'bg-red-500/20 text-red-400' : 'bg-yellow-500/20 text-yellow-400',
68
+ )}>
69
+ {action}
70
+ </span>
71
+ )
72
+ }
73
+ case 'rules': {
74
+ const count = getKyvernoPolicyRuleCount(resource)
75
+ return <span className="text-sm text-theme-text-secondary">{count}</span>
76
+ }
77
+ default:
78
+ return <span className="text-sm text-theme-text-tertiary">-</span>
79
+ }
80
+ }
81
+
82
+ export function ClusterPolicyCell({ resource, column }: { resource: any; column: string }) {
83
+ // Same rendering logic as KyvernoPolicy
84
+ return <KyvernoPolicyCell resource={resource} column={column} />
85
+ }
@@ -0,0 +1,74 @@
1
+ // Prometheus Operator cell components for ResourcesView table
2
+
3
+ import { clsx } from 'clsx'
4
+ import {
5
+ getServiceMonitorStatus,
6
+ getServiceMonitorEndpointCount,
7
+ getServiceMonitorJobLabel,
8
+ getServiceMonitorSelector,
9
+ getPrometheusRuleStatus,
10
+ getPrometheusRuleGroupCount,
11
+ getPrometheusRuleTotalRules,
12
+ getPodMonitorStatus,
13
+ getPodMonitorEndpointCount,
14
+ getPodMonitorSelector,
15
+ } from '../resource-utils-prometheus'
16
+
17
+ export function ServiceMonitorCell({ resource, column }: { resource: any; column: string }) {
18
+ switch (column) {
19
+ case 'status': {
20
+ const status = getServiceMonitorStatus(resource)
21
+ return (
22
+ <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
23
+ {status.text}
24
+ </span>
25
+ )
26
+ }
27
+ case 'endpoints':
28
+ return <span className="text-sm text-theme-text-secondary">{getServiceMonitorEndpointCount(resource)}</span>
29
+ case 'jobLabel':
30
+ return <span className="text-sm text-theme-text-secondary truncate block">{getServiceMonitorJobLabel(resource)}</span>
31
+ case 'selector':
32
+ return <span className="text-sm text-theme-text-secondary truncate block">{getServiceMonitorSelector(resource)}</span>
33
+ default:
34
+ return <span className="text-sm text-theme-text-tertiary">-</span>
35
+ }
36
+ }
37
+
38
+ export function PrometheusRuleCell({ resource, column }: { resource: any; column: string }) {
39
+ switch (column) {
40
+ case 'status': {
41
+ const status = getPrometheusRuleStatus(resource)
42
+ return (
43
+ <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
44
+ {status.text}
45
+ </span>
46
+ )
47
+ }
48
+ case 'groups':
49
+ return <span className="text-sm text-theme-text-secondary">{getPrometheusRuleGroupCount(resource)}</span>
50
+ case 'rules':
51
+ return <span className="text-sm text-theme-text-secondary">{getPrometheusRuleTotalRules(resource)}</span>
52
+ default:
53
+ return <span className="text-sm text-theme-text-tertiary">-</span>
54
+ }
55
+ }
56
+
57
+ export function PodMonitorCell({ resource, column }: { resource: any; column: string }) {
58
+ switch (column) {
59
+ case 'status': {
60
+ const status = getPodMonitorStatus(resource)
61
+ return (
62
+ <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
63
+ {status.text}
64
+ </span>
65
+ )
66
+ }
67
+ case 'endpoints':
68
+ return <span className="text-sm text-theme-text-secondary">{getPodMonitorEndpointCount(resource)}</span>
69
+ case 'selector':
70
+ return <span className="text-sm text-theme-text-secondary truncate block">{getPodMonitorSelector(resource)}</span>
71
+ default:
72
+ return <span className="text-sm text-theme-text-tertiary">-</span>
73
+ }
74
+ }