@skyhook-io/k8s-ui 1.2.3 → 1.3.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 (118) hide show
  1. package/package.json +3 -2
  2. package/src/components/dock/BottomDock.tsx +1 -1
  3. package/src/components/dock/LocalTerminalTab.tsx +1 -1
  4. package/src/components/dock/NodeTerminalTab.tsx +1 -1
  5. package/src/components/dock/TerminalTab.tsx +2 -2
  6. package/src/components/gitops/GitOpsActions.tsx +12 -11
  7. package/src/components/gitops/GitOpsStatusBadge.tsx +6 -6
  8. package/src/components/logs/LogCore.tsx +8 -8
  9. package/src/components/logs/WorkloadLogsViewer.tsx +29 -5
  10. package/src/components/logs/useLogStream.ts +20 -0
  11. package/src/components/resources/ResourcesSidebar.tsx +10 -10
  12. package/src/components/resources/ResourcesView.tsx +49 -48
  13. package/src/components/resources/renderers/AlertRenderer.tsx +2 -2
  14. package/src/components/resources/renderers/ArgoApplicationRenderer.tsx +2 -2
  15. package/src/components/resources/renderers/CNPGClusterRenderer.tsx +1 -1
  16. package/src/components/resources/renderers/CertificateRenderer.tsx +3 -3
  17. package/src/components/resources/renderers/CertificateRequestRenderer.tsx +3 -3
  18. package/src/components/resources/renderers/ChallengeRenderer.tsx +2 -2
  19. package/src/components/resources/renderers/ClusterExternalSecretRenderer.tsx +3 -3
  20. package/src/components/resources/renderers/ClusterIssuerRenderer.tsx +3 -3
  21. package/src/components/resources/renderers/ConfigAuditReportRenderer.tsx +2 -2
  22. package/src/components/resources/renderers/ContourHTTPProxyRenderer.tsx +1 -1
  23. package/src/components/resources/renderers/EventRenderer.tsx +1 -1
  24. package/src/components/resources/renderers/ExposedSecretReportRenderer.tsx +2 -2
  25. package/src/components/resources/renderers/ExternalSecretRenderer.tsx +2 -2
  26. package/src/components/resources/renderers/FluxHelmReleaseRenderer.tsx +1 -1
  27. package/src/components/resources/renderers/GRPCRouteRenderer.tsx +5 -5
  28. package/src/components/resources/renderers/GatewayClassRenderer.tsx +1 -1
  29. package/src/components/resources/renderers/GatewayRenderer.tsx +3 -3
  30. package/src/components/resources/renderers/GenericRenderer.tsx +1 -1
  31. package/src/components/resources/renderers/HPARenderer.tsx +1 -1
  32. package/src/components/resources/renderers/HTTPRouteRenderer.tsx +5 -5
  33. package/src/components/resources/renderers/HelmRepositoryRenderer.tsx +1 -1
  34. package/src/components/resources/renderers/IngressClassRenderer.tsx +1 -1
  35. package/src/components/resources/renderers/IngressRenderer.tsx +1 -1
  36. package/src/components/resources/renderers/IstioAuthorizationPolicyRenderer.tsx +10 -10
  37. package/src/components/resources/renderers/IstioDestinationRuleRenderer.tsx +1 -1
  38. package/src/components/resources/renderers/IstioGatewayRenderer.tsx +2 -2
  39. package/src/components/resources/renderers/IstioPeerAuthenticationRenderer.tsx +2 -2
  40. package/src/components/resources/renderers/IstioServiceEntryRenderer.tsx +6 -6
  41. package/src/components/resources/renderers/IstioVirtualServiceRenderer.tsx +5 -5
  42. package/src/components/resources/renderers/KarpenterEC2NodeClassRenderer.tsx +5 -5
  43. package/src/components/resources/renderers/KarpenterNodeClaimRenderer.tsx +2 -2
  44. package/src/components/resources/renderers/KarpenterNodePoolRenderer.tsx +4 -4
  45. package/src/components/resources/renderers/KedaScaledJobRenderer.tsx +3 -3
  46. package/src/components/resources/renderers/KedaScaledObjectRenderer.tsx +3 -3
  47. package/src/components/resources/renderers/KedaTriggerAuthRenderer.tsx +5 -5
  48. package/src/components/resources/renderers/KnativeConfigurationRenderer.tsx +2 -2
  49. package/src/components/resources/renderers/KnativeEventingRenderer.tsx +5 -5
  50. package/src/components/resources/renderers/KnativeFlowRenderer.tsx +4 -4
  51. package/src/components/resources/renderers/KnativeNetworkingRenderer.tsx +8 -8
  52. package/src/components/resources/renderers/KnativeRevisionRenderer.tsx +3 -3
  53. package/src/components/resources/renderers/KnativeRouteRenderer.tsx +1 -1
  54. package/src/components/resources/renderers/KnativeServiceRenderer.tsx +2 -2
  55. package/src/components/resources/renderers/KnativeSourceRenderer.tsx +6 -6
  56. package/src/components/resources/renderers/KustomizationRenderer.tsx +1 -1
  57. package/src/components/resources/renderers/KyvernoPolicyReportRenderer.tsx +4 -4
  58. package/src/components/resources/renderers/NetworkPolicyRenderer.tsx +6 -6
  59. package/src/components/resources/renderers/NodeRenderer.tsx +5 -5
  60. package/src/components/resources/renderers/OrderRenderer.tsx +3 -3
  61. package/src/components/resources/renderers/PersistentVolumeRenderer.tsx +1 -1
  62. package/src/components/resources/renderers/PodDisruptionBudgetRenderer.tsx +1 -1
  63. package/src/components/resources/renderers/PodMonitorRenderer.tsx +3 -3
  64. package/src/components/resources/renderers/PodRenderer.tsx +10 -10
  65. package/src/components/resources/renderers/PrometheusRuleRenderer.tsx +2 -2
  66. package/src/components/resources/renderers/RoleBindingRenderer.tsx +3 -3
  67. package/src/components/resources/renderers/RoleRenderer.tsx +8 -8
  68. package/src/components/resources/renderers/RolloutRenderer.tsx +1 -1
  69. package/src/components/resources/renderers/RuntimeClassRenderer.tsx +2 -2
  70. package/src/components/resources/renderers/SealedSecretRenderer.tsx +2 -2
  71. package/src/components/resources/renderers/SecretRenderer.tsx +3 -3
  72. package/src/components/resources/renderers/ServiceAccountRenderer.tsx +1 -1
  73. package/src/components/resources/renderers/ServiceMonitorRenderer.tsx +3 -3
  74. package/src/components/resources/renderers/ServiceRenderer.tsx +1 -1
  75. package/src/components/resources/renderers/SimpleRouteRenderer.tsx +5 -5
  76. package/src/components/resources/renderers/StorageClassRenderer.tsx +1 -1
  77. package/src/components/resources/renderers/TraefikIngressRouteRenderer.tsx +1 -1
  78. package/src/components/resources/renderers/VPARenderer.tsx +2 -2
  79. package/src/components/resources/renderers/VeleroBSLRenderer.tsx +2 -2
  80. package/src/components/resources/renderers/VeleroBackupRenderer.tsx +6 -6
  81. package/src/components/resources/renderers/VeleroRestoreRenderer.tsx +5 -5
  82. package/src/components/resources/renderers/VeleroScheduleRenderer.tsx +6 -6
  83. package/src/components/resources/renderers/VeleroVSLRenderer.tsx +1 -1
  84. package/src/components/resources/renderers/WebhookConfigRenderer.tsx +10 -10
  85. package/src/components/resources/renderers/WorkflowRenderer.tsx +2 -2
  86. package/src/components/resources/renderers/WorkflowTemplateRenderer.tsx +2 -2
  87. package/src/components/resources/renderers/WorkloadRenderer.tsx +1 -1
  88. package/src/components/resources/renderers/argo-cells.tsx +3 -3
  89. package/src/components/resources/renderers/certmanager-cells.tsx +6 -6
  90. package/src/components/resources/renderers/cnpg-cells.tsx +5 -5
  91. package/src/components/resources/renderers/eso-cells.tsx +4 -4
  92. package/src/components/resources/renderers/flux-cells.tsx +6 -6
  93. package/src/components/resources/renderers/istio-cells.tsx +9 -9
  94. package/src/components/resources/renderers/karpenter-cells.tsx +3 -3
  95. package/src/components/resources/renderers/keda-cells.tsx +2 -2
  96. package/src/components/resources/renderers/knative-cells.tsx +2 -2
  97. package/src/components/resources/renderers/kyverno-cells.tsx +3 -3
  98. package/src/components/resources/renderers/prometheus-cells.tsx +3 -3
  99. package/src/components/resources/renderers/trivy-cells.tsx +4 -4
  100. package/src/components/resources/renderers/velero-cells.tsx +4 -4
  101. package/src/components/shared/EditableYamlView.tsx +1 -1
  102. package/src/components/shared/ResourceActionsBar.tsx +17 -17
  103. package/src/components/shared/ResourceRendererDispatch.tsx +8 -7
  104. package/src/components/topology/K8sResourceNode.tsx +5 -5
  105. package/src/components/topology/TopologyControls.tsx +2 -2
  106. package/src/components/topology/TopologyGraph.tsx +89 -23
  107. package/src/components/topology/topology.css +1 -1
  108. package/src/components/ui/Badge.tsx +178 -0
  109. package/src/components/ui/HealthRing.tsx +70 -35
  110. package/src/components/ui/MetricsChart.tsx +2 -2
  111. package/src/components/ui/drawer-components.tsx +12 -31
  112. package/src/components/workload/ResourceDetailDrawer.tsx +4 -4
  113. package/src/components/workload/WorkloadView.tsx +10 -10
  114. package/src/theme/components.css +195 -0
  115. package/src/theme/tailwind-theme.css +13 -13
  116. package/src/theme/variables.css +46 -29
  117. package/src/types/core.ts +2 -0
  118. package/src/utils/badge-colors.ts +54 -205
@@ -28,7 +28,7 @@ export function CertificateCell({ resource, column }: { resource: any; column: s
28
28
  case 'status': {
29
29
  const status = getCertificateStatus(resource)
30
30
  return (
31
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
31
+ <span className={clsx('badge', status.color)}>
32
32
  {status.text}
33
33
  </span>
34
34
  )
@@ -69,7 +69,7 @@ export function CertificateRequestCell({ resource, column }: { resource: any; co
69
69
  case 'status': {
70
70
  const status = getCertificateRequestStatus(resource)
71
71
  return (
72
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
72
+ <span className={clsx('badge', status.color)}>
73
73
  {status.text}
74
74
  </span>
75
75
  )
@@ -88,7 +88,7 @@ export function ClusterIssuerCell({ resource, column }: { resource: any; column:
88
88
  case 'status': {
89
89
  const status = getClusterIssuerStatus(resource)
90
90
  return (
91
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
91
+ <span className={clsx('badge', status.color)}>
92
92
  {status.text}
93
93
  </span>
94
94
  )
@@ -105,7 +105,7 @@ export function IssuerCell({ resource, column }: { resource: any; column: string
105
105
  case 'status': {
106
106
  const status = getIssuerStatus(resource)
107
107
  return (
108
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
108
+ <span className={clsx('badge', status.color)}>
109
109
  {status.text}
110
110
  </span>
111
111
  )
@@ -122,7 +122,7 @@ export function OrderCell({ resource, column }: { resource: any; column: string
122
122
  case 'state': {
123
123
  const state = getOrderState(resource)
124
124
  return (
125
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', state.color)}>
125
+ <span className={clsx('badge', state.color)}>
126
126
  {state.text}
127
127
  </span>
128
128
  )
@@ -147,7 +147,7 @@ export function ChallengeCell({ resource, column }: { resource: any; column: str
147
147
  case 'state': {
148
148
  const state = getChallengeState(resource)
149
149
  return (
150
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', state.color)}>
150
+ <span className={clsx('badge', state.color)}>
151
151
  {state.text}
152
152
  </span>
153
153
  )
@@ -28,7 +28,7 @@ export function CNPGClusterCell({ resource, column }: { resource: any; column: s
28
28
  case 'status': {
29
29
  const status = getCNPGClusterStatus(resource)
30
30
  return (
31
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
31
+ <span className={clsx('badge', status.color)}>
32
32
  {status.text}
33
33
  </span>
34
34
  )
@@ -65,7 +65,7 @@ export function CNPGBackupCell({ resource, column }: { resource: any; column: st
65
65
  case 'status': {
66
66
  const status = getCNPGBackupStatus(resource)
67
67
  return (
68
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
68
+ <span className={clsx('badge', status.color)}>
69
69
  {status.text}
70
70
  </span>
71
71
  )
@@ -92,7 +92,7 @@ export function CNPGScheduledBackupCell({ resource, column }: { resource: any; c
92
92
  case 'status': {
93
93
  const status = getCNPGScheduledBackupStatus(resource)
94
94
  return (
95
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
95
+ <span className={clsx('badge', status.color)}>
96
96
  {status.text}
97
97
  </span>
98
98
  )
@@ -127,7 +127,7 @@ export function CNPGPoolerCell({ resource, column }: { resource: any; column: st
127
127
  case 'status': {
128
128
  const status = getCNPGPoolerStatus(resource)
129
129
  return (
130
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
130
+ <span className={clsx('badge', status.color)}>
131
131
  {status.text}
132
132
  </span>
133
133
  )
@@ -140,7 +140,7 @@ export function CNPGPoolerCell({ resource, column }: { resource: any; column: st
140
140
  const type = getCNPGPoolerType(resource)
141
141
  return (
142
142
  <span className={clsx(
143
- 'inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium',
143
+ 'badge-sm',
144
144
  type === 'rw' ? 'bg-blue-500/20 text-blue-400' : 'bg-purple-500/20 text-purple-400'
145
145
  )}>
146
146
  {type}
@@ -20,7 +20,7 @@ export function ExternalSecretCell({ resource, column }: { resource: any; column
20
20
  case 'status': {
21
21
  const status = getExternalSecretStatus(resource)
22
22
  return (
23
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
23
+ <span className={clsx('badge', status.color)}>
24
24
  {status.text}
25
25
  </span>
26
26
  )
@@ -55,7 +55,7 @@ export function ClusterExternalSecretCell({ resource, column }: { resource: any;
55
55
  case 'status': {
56
56
  const status = getClusterExternalSecretStatus(resource)
57
57
  return (
58
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
58
+ <span className={clsx('badge', status.color)}>
59
59
  {status.text}
60
60
  </span>
61
61
  )
@@ -81,7 +81,7 @@ export function SecretStoreCell({ resource, column }: { resource: any; column: s
81
81
  case 'status': {
82
82
  const status = getSecretStoreStatus(resource)
83
83
  return (
84
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
84
+ <span className={clsx('badge', status.color)}>
85
85
  {status.text}
86
86
  </span>
87
87
  )
@@ -100,7 +100,7 @@ export function ClusterSecretStoreCell({ resource, column }: { resource: any; co
100
100
  case 'status': {
101
101
  const status = getClusterSecretStoreStatus(resource)
102
102
  return (
103
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
103
+ <span className={clsx('badge', status.color)}>
104
104
  {status.text}
105
105
  </span>
106
106
  )
@@ -45,7 +45,7 @@ export function GitRepositoryCell({ resource, column }: { resource: any; column:
45
45
  case 'status': {
46
46
  const status = getGitRepositoryStatus(resource)
47
47
  return (
48
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
48
+ <span className={clsx('badge', status.color)}>
49
49
  {status.text}
50
50
  </span>
51
51
  )
@@ -78,7 +78,7 @@ export function OCIRepositoryCell({ resource, column }: { resource: any; column:
78
78
  case 'status': {
79
79
  const status = getOCIRepositoryStatus(resource)
80
80
  return (
81
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
81
+ <span className={clsx('badge', status.color)}>
82
82
  {status.text}
83
83
  </span>
84
84
  )
@@ -111,7 +111,7 @@ export function HelmRepositoryCell({ resource, column }: { resource: any; column
111
111
  case 'status': {
112
112
  const status = getHelmRepositoryStatus(resource)
113
113
  return (
114
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
114
+ <span className={clsx('badge', status.color)}>
115
115
  {status.text}
116
116
  </span>
117
117
  )
@@ -138,7 +138,7 @@ export function KustomizationCell({ resource, column }: { resource: any; column:
138
138
  case 'status': {
139
139
  const status = getKustomizationStatus(resource)
140
140
  return (
141
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
141
+ <span className={clsx('badge', status.color)}>
142
142
  {status.text}
143
143
  </span>
144
144
  )
@@ -197,7 +197,7 @@ export function FluxHelmReleaseCell({ resource, column }: { resource: any; colum
197
197
  case 'status': {
198
198
  const status = getFluxHelmReleaseStatus(resource)
199
199
  return (
200
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
200
+ <span className={clsx('badge', status.color)}>
201
201
  {status.text}
202
202
  </span>
203
203
  )
@@ -242,7 +242,7 @@ export function FluxAlertCell({ resource, column }: { resource: any; column: str
242
242
  case 'status': {
243
243
  const status = getFluxAlertStatus(resource)
244
244
  return (
245
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
245
+ <span className={clsx('badge', status.color)}>
246
246
  {status.text}
247
247
  </span>
248
248
  )
@@ -43,7 +43,7 @@ export function VirtualServiceCell({ resource, column }: { resource: any; column
43
43
  case 'status': {
44
44
  const status = getVirtualServiceStatus(resource)
45
45
  return (
46
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
46
+ <span className={clsx('badge', status.color)}>
47
47
  {status.text}
48
48
  </span>
49
49
  )
@@ -70,7 +70,7 @@ export function DestinationRuleCell({ resource, column }: { resource: any; colum
70
70
  case 'status': {
71
71
  const status = getDestinationRuleStatus(resource)
72
72
  return (
73
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
73
+ <span className={clsx('badge', status.color)}>
74
74
  {status.text}
75
75
  </span>
76
76
  )
@@ -97,7 +97,7 @@ export function IstioGatewayCell({ resource, column }: { resource: any; column:
97
97
  case 'status': {
98
98
  const status = getIstioGatewayStatus(resource)
99
99
  return (
100
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
100
+ <span className={clsx('badge', status.color)}>
101
101
  {status.text}
102
102
  </span>
103
103
  )
@@ -120,7 +120,7 @@ export function ServiceEntryCell({ resource, column }: { resource: any; column:
120
120
  case 'status': {
121
121
  const status = getServiceEntryStatus(resource)
122
122
  return (
123
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
123
+ <span className={clsx('badge', status.color)}>
124
124
  {status.text}
125
125
  </span>
126
126
  )
@@ -133,7 +133,7 @@ export function ServiceEntryCell({ resource, column }: { resource: any; column:
133
133
  const location = getServiceEntryLocation(resource)
134
134
  return (
135
135
  <span className={clsx(
136
- 'inline-flex items-center px-2 py-0.5 rounded text-xs font-medium',
136
+ 'badge',
137
137
  location === 'MESH_EXTERNAL' ? 'bg-orange-500/20 text-orange-400' : 'bg-blue-500/20 text-blue-400'
138
138
  )}>
139
139
  {location === 'MESH_EXTERNAL' ? 'External' : 'Internal'}
@@ -154,7 +154,7 @@ export function PeerAuthenticationCell({ resource, column }: { resource: any; co
154
154
  case 'status': {
155
155
  const status = getPeerAuthenticationStatus(resource)
156
156
  return (
157
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
157
+ <span className={clsx('badge', status.color)}>
158
158
  {status.text}
159
159
  </span>
160
160
  )
@@ -163,7 +163,7 @@ export function PeerAuthenticationCell({ resource, column }: { resource: any; co
163
163
  const mode = getPeerAuthenticationMode(resource)
164
164
  return (
165
165
  <span className={clsx(
166
- 'inline-flex items-center px-2 py-0.5 rounded text-xs font-medium',
166
+ 'badge',
167
167
  modeColors[mode] || 'bg-gray-500/20 text-gray-400'
168
168
  )}>
169
169
  {mode}
@@ -184,7 +184,7 @@ export function AuthorizationPolicyCell({ resource, column }: { resource: any; c
184
184
  case 'status': {
185
185
  const status = getAuthorizationPolicyStatus(resource)
186
186
  return (
187
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
187
+ <span className={clsx('badge', status.color)}>
188
188
  {status.text}
189
189
  </span>
190
190
  )
@@ -193,7 +193,7 @@ export function AuthorizationPolicyCell({ resource, column }: { resource: any; c
193
193
  const action = getAuthorizationPolicyAction(resource)
194
194
  return (
195
195
  <span className={clsx(
196
- 'inline-flex items-center px-2 py-0.5 rounded text-xs font-medium',
196
+ 'badge',
197
197
  actionColors[action] || 'bg-gray-500/20 text-gray-400'
198
198
  )}>
199
199
  {action}
@@ -22,7 +22,7 @@ export function NodePoolCell({ resource, column }: { resource: any; column: stri
22
22
  case 'status': {
23
23
  const status = getNodePoolStatus(resource)
24
24
  return (
25
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
25
+ <span className={clsx('badge', status.color)}>
26
26
  {status.text}
27
27
  </span>
28
28
  )
@@ -53,7 +53,7 @@ export function NodeClaimCell({ resource, column }: { resource: any; column: str
53
53
  case 'status': {
54
54
  const status = getNodeClaimStatus(resource)
55
55
  return (
56
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
56
+ <span className={clsx('badge', status.color)}>
57
57
  {status.text}
58
58
  </span>
59
59
  )
@@ -80,7 +80,7 @@ export function EC2NodeClassCell({ resource, column }: { resource: any; column:
80
80
  case 'status': {
81
81
  const status = getEC2NodeClassStatus(resource)
82
82
  return (
83
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
83
+ <span className={clsx('badge', status.color)}>
84
84
  {status.text}
85
85
  </span>
86
86
  )
@@ -20,7 +20,7 @@ export function ScaledObjectCell({ resource, column }: { resource: any; column:
20
20
  case 'status': {
21
21
  const status = getScaledObjectStatus(resource)
22
22
  return (
23
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
23
+ <span className={clsx('badge', status.color)}>
24
24
  {status.text}
25
25
  </span>
26
26
  )
@@ -47,7 +47,7 @@ export function ScaledJobCell({ resource, column }: { resource: any; column: str
47
47
  case 'status': {
48
48
  const status = getScaledJobStatus(resource)
49
49
  return (
50
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
50
+ <span className={clsx('badge', status.color)}>
51
51
  {status.text}
52
52
  </span>
53
53
  )
@@ -32,7 +32,7 @@ import {
32
32
  function StatusCell({ resource, getStatus }: { resource: any; getStatus: (r: any) => { text: string; color: string } }) {
33
33
  const status = getStatus(resource)
34
34
  return (
35
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
35
+ <span className={clsx('badge', status.color)}>
36
36
  {status.text}
37
37
  </span>
38
38
  )
@@ -383,7 +383,7 @@ export function ServerlessServiceCell({ resource, column }: { resource: any; col
383
383
  const mode = getServerlessServiceMode(resource)
384
384
  return (
385
385
  <span className={clsx(
386
- 'inline-flex items-center px-2 py-0.5 rounded text-xs font-medium',
386
+ 'badge',
387
387
  mode === 'Proxy' ? 'bg-yellow-500/20 text-yellow-400' : 'bg-green-500/20 text-green-400'
388
388
  )}>
389
389
  {mode}
@@ -14,7 +14,7 @@ export function PolicyReportCell({ resource, column }: { resource: any; column:
14
14
  case 'status': {
15
15
  const status = getPolicyReportStatus(resource)
16
16
  return (
17
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
17
+ <span className={clsx('badge', status.color)}>
18
18
  {status.text}
19
19
  </span>
20
20
  )
@@ -54,7 +54,7 @@ export function KyvernoPolicyCell({ resource, column }: { resource: any; column:
54
54
  case 'status': {
55
55
  const status = getKyvernoPolicyStatus(resource)
56
56
  return (
57
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
57
+ <span className={clsx('badge', status.color)}>
58
58
  {status.text}
59
59
  </span>
60
60
  )
@@ -63,7 +63,7 @@ export function KyvernoPolicyCell({ resource, column }: { resource: any; column:
63
63
  const action = getKyvernoPolicyAction(resource)
64
64
  return (
65
65
  <span className={clsx(
66
- 'inline-flex items-center px-2 py-0.5 rounded text-xs font-medium',
66
+ 'badge',
67
67
  action === 'Enforce' ? 'bg-red-500/20 text-red-400' : 'bg-yellow-500/20 text-yellow-400',
68
68
  )}>
69
69
  {action}
@@ -19,7 +19,7 @@ export function ServiceMonitorCell({ resource, column }: { resource: any; column
19
19
  case 'status': {
20
20
  const status = getServiceMonitorStatus(resource)
21
21
  return (
22
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
22
+ <span className={clsx('badge', status.color)}>
23
23
  {status.text}
24
24
  </span>
25
25
  )
@@ -40,7 +40,7 @@ export function PrometheusRuleCell({ resource, column }: { resource: any; column
40
40
  case 'status': {
41
41
  const status = getPrometheusRuleStatus(resource)
42
42
  return (
43
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
43
+ <span className={clsx('badge', status.color)}>
44
44
  {status.text}
45
45
  </span>
46
46
  )
@@ -59,7 +59,7 @@ export function PodMonitorCell({ resource, column }: { resource: any; column: st
59
59
  case 'status': {
60
60
  const status = getPodMonitorStatus(resource)
61
61
  return (
62
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
62
+ <span className={clsx('badge', status.color)}>
63
63
  {status.text}
64
64
  </span>
65
65
  )
@@ -60,7 +60,7 @@ export function ConfigAuditReportCell({ resource, column }: { resource: any; col
60
60
  case 'status': {
61
61
  const status = getConfigAuditReportStatus(resource)
62
62
  return (
63
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
63
+ <span className={clsx('badge', status.color)}>
64
64
  {status.text}
65
65
  </span>
66
66
  )
@@ -96,7 +96,7 @@ export function RbacAssessmentReportCell({ resource, column }: { resource: any;
96
96
  case 'status': {
97
97
  const status = getRbacAssessmentReportStatus(resource)
98
98
  return (
99
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
99
+ <span className={clsx('badge', status.color)}>
100
100
  {status.text}
101
101
  </span>
102
102
  )
@@ -113,7 +113,7 @@ export function ClusterComplianceReportCell({ resource, column }: { resource: an
113
113
  case 'status': {
114
114
  const status = getClusterComplianceReportStatus(resource)
115
115
  return (
116
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
116
+ <span className={clsx('badge', status.color)}>
117
117
  {status.text}
118
118
  </span>
119
119
  )
@@ -142,7 +142,7 @@ export function SbomReportCell({ resource, column }: { resource: any; column: st
142
142
  case 'status': {
143
143
  const status = getSbomReportStatus(resource)
144
144
  return (
145
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
145
+ <span className={clsx('badge', status.color)}>
146
146
  {status.text}
147
147
  </span>
148
148
  )
@@ -30,7 +30,7 @@ export function BackupCell({ resource, column }: { resource: any; column: string
30
30
  case 'status': {
31
31
  const status = getBackupStatus(resource)
32
32
  return (
33
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
33
+ <span className={clsx('badge', status.color)}>
34
34
  {status.text}
35
35
  </span>
36
36
  )
@@ -76,7 +76,7 @@ export function RestoreCell({ resource, column }: { resource: any; column: strin
76
76
  case 'status': {
77
77
  const status = getRestoreStatus(resource)
78
78
  return (
79
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
79
+ <span className={clsx('badge', status.color)}>
80
80
  {status.text}
81
81
  </span>
82
82
  )
@@ -110,7 +110,7 @@ export function ScheduleCell({ resource, column }: { resource: any; column: stri
110
110
  case 'status': {
111
111
  const status = getScheduleStatus(resource)
112
112
  return (
113
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
113
+ <span className={clsx('badge', status.color)}>
114
114
  {status.text}
115
115
  </span>
116
116
  )
@@ -137,7 +137,7 @@ export function BackupStorageLocationCell({ resource, column }: { resource: any;
137
137
  case 'status': {
138
138
  const status = getBSLStatus(resource)
139
139
  return (
140
- <span className={clsx('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', status.color)}>
140
+ <span className={clsx('badge', status.color)}>
141
141
  {status.text}
142
142
  </span>
143
143
  )
@@ -184,7 +184,7 @@ export function EditableYamlView({ resource, data, onCopy, copied, onSaved, onSa
184
184
  <button
185
185
  onClick={handleSaveEdit}
186
186
  disabled={isPending || yamlErrors.length > 0}
187
- className="flex items-center gap-1 px-3 py-1.5 text-xs text-white bg-blue-600 hover:bg-blue-700 rounded disabled:opacity-50 disabled:cursor-not-allowed"
187
+ className="flex items-center gap-1 px-3 py-1.5 text-xs btn-brand rounded disabled:cursor-not-allowed"
188
188
  >
189
189
  {isPending ? (
190
190
  <RefreshCw className="w-3.5 h-3.5 animate-spin" />
@@ -204,7 +204,7 @@ export function ResourceActionsBar({
204
204
  {isRunning && canExec && onOpenTerminal && (
205
205
  <button
206
206
  onClick={handleOpenTerminal}
207
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
207
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand rounded-lg"
208
208
  >
209
209
  <Terminal className="w-3.5 h-3.5" />
210
210
  Terminal
@@ -218,7 +218,7 @@ export function ResourceActionsBar({
218
218
  >
219
219
  <button
220
220
  onClick={() => handleOpenLogs(containers.length === 1 ? containers[0] : undefined)}
221
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-slate-600 hover:bg-slate-500 rounded-lg transition-colors"
221
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand-muted rounded-lg"
222
222
  >
223
223
  <FileText className="w-3.5 h-3.5" />
224
224
  Logs
@@ -260,7 +260,7 @@ export function ResourceActionsBar({
260
260
  {canExec && onOpenNodeTerminal && (
261
261
  <button
262
262
  onClick={() => onOpenNodeTerminal({ nodeName: resource.name })}
263
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
263
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand rounded-lg"
264
264
  >
265
265
  <Terminal className="w-3.5 h-3.5" />
266
266
  Debug Shell
@@ -329,7 +329,7 @@ export function ResourceActionsBar({
329
329
  name: resource.name,
330
330
  })}
331
331
  disabled={isRestarting}
332
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-slate-600 hover:bg-slate-500 rounded-lg transition-colors disabled:opacity-50"
332
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand-muted rounded-lg"
333
333
  >
334
334
  <RefreshCw className={`w-3.5 h-3.5 ${isRestarting ? 'animate-spin' : ''}`} />
335
335
  {isRestarting ? 'Restarting...' : 'Restart'}
@@ -358,7 +358,7 @@ export function ResourceActionsBar({
358
358
  workloadKind: kind,
359
359
  workloadName: resource.name,
360
360
  })}
361
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-slate-600 hover:bg-slate-500 rounded-lg transition-colors"
361
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand-muted rounded-lg"
362
362
  >
363
363
  <FileText className="w-3.5 h-3.5" />
364
364
  Logs
@@ -377,7 +377,7 @@ export function ResourceActionsBar({
377
377
  name: resource.name,
378
378
  })}
379
379
  disabled={isTriggeringCronJob}
380
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors disabled:opacity-50"
380
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand rounded-lg"
381
381
  >
382
382
  <Play className={`w-3.5 h-3.5 ${isTriggeringCronJob ? 'animate-pulse' : ''}`} />
383
383
  {isTriggeringCronJob ? 'Triggering...' : 'Trigger'}
@@ -405,7 +405,7 @@ export function ResourceActionsBar({
405
405
  name: resource.name,
406
406
  })}
407
407
  disabled={isSuspendingCronJob}
408
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-slate-600 hover:bg-slate-500 rounded-lg transition-colors disabled:opacity-50"
408
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand-muted rounded-lg"
409
409
  >
410
410
  <Pause className="w-3.5 h-3.5" />
411
411
  {isSuspendingCronJob ? 'Suspending...' : 'Suspend'}
@@ -455,7 +455,7 @@ export function ResourceActionsBar({
455
455
  'Logs command copied',
456
456
  e
457
457
  )}
458
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-slate-600 hover:bg-slate-500 rounded-lg transition-colors"
458
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand-muted rounded-lg"
459
459
  >
460
460
  <FileText className="w-3.5 h-3.5" />
461
461
  Logs
@@ -472,8 +472,8 @@ export function ResourceActionsBar({
472
472
  className={clsx(
473
473
  'flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg transition-colors',
474
474
  showYaml
475
- ? 'text-white bg-blue-600 hover:bg-blue-700'
476
- : 'text-theme-text-secondary hover:text-theme-text-primary border border-theme-border hover:bg-theme-elevated'
475
+ ? 'btn-brand'
476
+ : 'text-theme-text-secondary hover:text-theme-text-primary border border-theme-border-light hover:bg-theme-elevated'
477
477
  )}
478
478
  title="Toggle YAML view"
479
479
  >
@@ -596,7 +596,7 @@ function FluxActions({ resource, data, onReconcile, isReconciling, onSyncWithSou
596
596
  name: resource.name,
597
597
  })}
598
598
  disabled={isReconciling || isSuspended}
599
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors disabled:opacity-50"
599
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand rounded-lg"
600
600
  title={isSuspended ? 'Cannot reconcile while suspended' : 'Trigger reconciliation'}
601
601
  >
602
602
  <RefreshCw className={`w-3.5 h-3.5 ${isReconciling ? 'animate-spin' : ''}`} />
@@ -644,7 +644,7 @@ function FluxActions({ resource, data, onReconcile, isReconciling, onSyncWithSou
644
644
  name: resource.name,
645
645
  })}
646
646
  disabled={isSuspending}
647
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-slate-600 hover:bg-slate-500 rounded-lg transition-colors disabled:opacity-50"
647
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand-muted rounded-lg"
648
648
  >
649
649
  <Pause className="w-3.5 h-3.5" />
650
650
  {isSuspending ? 'Suspending...' : 'Suspend'}
@@ -677,7 +677,7 @@ function ArgoActions({ resource, data, onSync, isSyncing, onRefresh, isRefreshin
677
677
  name: resource.name,
678
678
  })}
679
679
  disabled={isSyncing}
680
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors disabled:opacity-50"
680
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand rounded-lg"
681
681
  title="Sync application"
682
682
  >
683
683
  <RefreshCw className={`w-3.5 h-3.5 ${isSyncing ? 'animate-spin' : ''}`} />
@@ -693,7 +693,7 @@ function ArgoActions({ resource, data, onSync, isSyncing, onRefresh, isRefreshin
693
693
  hard: false,
694
694
  })}
695
695
  disabled={isRefreshing}
696
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-slate-600 hover:bg-slate-500 rounded-lg transition-colors disabled:opacity-50"
696
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand-muted rounded-lg"
697
697
  title="Refresh (re-read from git)"
698
698
  >
699
699
  <RefreshCw className={`w-3.5 h-3.5 ${isRefreshing ? 'animate-spin' : ''}`} />
@@ -709,7 +709,7 @@ function ArgoActions({ resource, data, onSync, isSyncing, onRefresh, isRefreshin
709
709
  name: resource.name,
710
710
  })}
711
711
  disabled={isSuspending}
712
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-slate-600 hover:bg-slate-500 rounded-lg transition-colors disabled:opacity-50"
712
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium btn-brand-muted rounded-lg"
713
713
  >
714
714
  <Pause className="w-3.5 h-3.5" />
715
715
  {isSuspending ? 'Suspending...' : 'Suspend'}
@@ -808,7 +808,7 @@ export function RevisionHistoryDialog({ kind, namespace, name, open, onClose, re
808
808
  <History className="w-5 h-5 text-amber-500" />
809
809
  <h3 className="text-lg font-semibold text-theme-text-primary">Revision History</h3>
810
810
  {diffRevision && currentRevision && (
811
- <span className="flex items-center gap-1 ml-2 px-2 py-0.5 text-xs bg-blue-500/15 text-blue-400 rounded">
811
+ <span className="badge ml-2 bg-blue-500/15 text-blue-400">
812
812
  <GitCompare className="w-3 h-3" />
813
813
  #{currentRevision.number} vs #{diffRevision}
814
814
  </span>
@@ -889,7 +889,7 @@ export function RevisionHistoryDialog({ kind, namespace, name, open, onClose, re
889
889
  </button>
890
890
  )}
891
891
  {rev.isCurrent ? (
892
- <span className="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-green-500/20 text-green-400 rounded">
892
+ <span className="badge status-healthy">
893
893
  Current
894
894
  </span>
895
895
  ) : confirmRevision === rev.number ? (