@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,272 @@
1
+ /**
2
+ * Web Worker for ELK layout calculations.
3
+ * Moves expensive layout operations off the main thread.
4
+ *
5
+ * We use elk-api.js which doesn't spawn its own worker - we ARE the worker.
6
+ * The algorithms run synchronously here but off the main thread.
7
+ */
8
+ import ELK from 'elkjs/lib/elk-api.js'
9
+ import elkWorkerAlgorithm from 'elkjs/lib/elk-worker.min.js?url'
10
+
11
+ // Create ELK with explicit worker URL (runs the algorithm in our worker context)
12
+ const elk = new ELK({
13
+ workerUrl: elkWorkerAlgorithm,
14
+ })
15
+
16
+ // ELK options for laying out nodes within a single group
17
+ const elkOptionsGroup = {
18
+ 'elk.algorithm': 'layered',
19
+ 'elk.direction': 'RIGHT',
20
+ 'elk.layered.considerModelOrder.strategy': 'NODES_AND_EDGES',
21
+ 'elk.spacing.nodeNode': '40',
22
+ 'elk.layered.spacing.nodeNodeBetweenLayers': '85',
23
+ 'elk.layered.spacing.edgeNodeBetweenLayers': '25',
24
+ 'elk.edgeRouting': 'ORTHOGONAL',
25
+ 'elk.layered.nodePlacement.strategy': 'NETWORK_SIMPLEX',
26
+ }
27
+
28
+ // ELK options for positioning groups based on inter-group connections
29
+ const elkOptionsGroupLayout = {
30
+ 'elk.algorithm': 'layered',
31
+ 'elk.direction': 'RIGHT',
32
+ 'elk.layered.considerModelOrder.strategy': 'NODES_AND_EDGES',
33
+ 'elk.spacing.nodeNode': '80',
34
+ 'elk.layered.spacing.nodeNodeBetweenLayers': '120',
35
+ 'elk.edgeRouting': 'ORTHOGONAL',
36
+ 'elk.layered.nodePlacement.strategy': 'NETWORK_SIMPLEX',
37
+ }
38
+
39
+ interface ElkNode {
40
+ id: string
41
+ width?: number
42
+ height?: number
43
+ children?: ElkNode[]
44
+ layoutOptions?: Record<string, string>
45
+ labels?: Array<{ text: string }>
46
+ }
47
+
48
+ interface ElkEdge {
49
+ id: string
50
+ sources: string[]
51
+ targets: string[]
52
+ }
53
+
54
+ interface ElkGraph {
55
+ id: string
56
+ layoutOptions: Record<string, string>
57
+ children: ElkNode[]
58
+ edges: ElkEdge[]
59
+ }
60
+
61
+ interface ElkLayoutResult {
62
+ id: string
63
+ x?: number
64
+ y?: number
65
+ width?: number
66
+ height?: number
67
+ children?: ElkLayoutResult[]
68
+ }
69
+
70
+ interface GroupPadding {
71
+ top: number
72
+ left: number
73
+ bottom: number
74
+ right: number
75
+ }
76
+
77
+ interface LayoutRequest {
78
+ type: 'layout'
79
+ requestId: number
80
+ elkGraph: ElkGraph
81
+ groupingMode: string
82
+ hideGroupHeader: boolean
83
+ padding: GroupPadding
84
+ }
85
+
86
+ interface GroupLayoutResult {
87
+ groupId: string
88
+ groupKey: string
89
+ width: number
90
+ height: number
91
+ children: Array<{ id: string; x: number; y: number }>
92
+ isCollapsed: boolean
93
+ }
94
+
95
+ interface UngroupedNodeResult {
96
+ id: string
97
+ width: number
98
+ height: number
99
+ }
100
+
101
+ interface LayoutResponse {
102
+ type: 'layout-result'
103
+ requestId: number
104
+ groupLayouts: GroupLayoutResult[]
105
+ ungroupedNodes: UngroupedNodeResult[]
106
+ groupPositions: Array<[string, { x: number; y: number }]>
107
+ error?: string
108
+ }
109
+
110
+ self.onmessage = async (e: MessageEvent<LayoutRequest>) => {
111
+ const { type, requestId, elkGraph, groupingMode, hideGroupHeader, padding } = e.data
112
+
113
+ if (type !== 'layout') return
114
+
115
+ try {
116
+ const groupLayouts: GroupLayoutResult[] = []
117
+ const ungroupedNodes: UngroupedNodeResult[] = []
118
+
119
+ // Build a set of node IDs in each group for edge filtering
120
+ const groupNodeIds = new Map<string, Set<string>>()
121
+
122
+ // Phase 1: Layout each group independently
123
+ for (const child of elkGraph.children) {
124
+ const isGroup = child.id.startsWith('group-')
125
+
126
+ if (isGroup && child.children && child.children.length > 0) {
127
+ const groupKey = child.id.replace(`group-${groupingMode}-`, '')
128
+ const minWidth = hideGroupHeader ? 300 : Math.max(500, groupKey.length * 16 + 200)
129
+
130
+ // Track node IDs in this group
131
+ const nodeIds = new Set(child.children.map(c => c.id))
132
+ groupNodeIds.set(child.id, nodeIds)
133
+
134
+ // Layout this group independently with only intra-group edges
135
+ const intraGroupEdges = elkGraph.edges.filter(e =>
136
+ nodeIds.has(e.sources[0]) && nodeIds.has(e.targets[0])
137
+ )
138
+
139
+ const groupGraph: ElkGraph = {
140
+ id: child.id,
141
+ layoutOptions: {
142
+ ...elkOptionsGroup,
143
+ 'elk.padding': `[left=${padding.left}, top=${padding.top}, right=${padding.right}, bottom=${padding.bottom}]`,
144
+ },
145
+ children: child.children,
146
+ edges: intraGroupEdges,
147
+ }
148
+
149
+ const layoutResult = await elk.layout(groupGraph) as ElkLayoutResult
150
+
151
+ const finalWidth = hideGroupHeader
152
+ ? (layoutResult.width || 300)
153
+ : Math.max(layoutResult.width || 300, minWidth)
154
+
155
+ groupLayouts.push({
156
+ groupId: child.id,
157
+ groupKey,
158
+ width: finalWidth,
159
+ height: layoutResult.height || 200,
160
+ children: (layoutResult.children || []).map(c => ({
161
+ id: c.id,
162
+ x: c.x || 0,
163
+ y: c.y || 0,
164
+ })),
165
+ isCollapsed: false,
166
+ })
167
+ } else if (isGroup) {
168
+ // Collapsed group
169
+ const groupKey = child.id.replace(`group-${groupingMode}-`, '')
170
+ const minWidth = Math.max(400, groupKey.length * 16 + 180)
171
+ groupLayouts.push({
172
+ groupId: child.id,
173
+ groupKey,
174
+ width: Math.max(child.width || 280, minWidth),
175
+ height: child.height || 90,
176
+ children: [],
177
+ isCollapsed: true,
178
+ })
179
+ } else {
180
+ // Ungrouped node
181
+ ungroupedNodes.push({
182
+ id: child.id,
183
+ width: child.width || 200,
184
+ height: child.height || 56,
185
+ })
186
+ }
187
+ }
188
+
189
+ // Phase 2: Build meta-graph and position groups
190
+ const nodeToGroup = new Map<string, string>()
191
+ for (const [groupId, nodeIds] of groupNodeIds) {
192
+ for (const nodeId of nodeIds) {
193
+ nodeToGroup.set(nodeId, groupId)
194
+ }
195
+ }
196
+
197
+ // Find inter-group edges
198
+ const interGroupEdges: ElkEdge[] = []
199
+ const seenInterGroupEdges = new Set<string>()
200
+
201
+ for (const edge of elkGraph.edges) {
202
+ const sourceGroup = nodeToGroup.get(edge.sources[0])
203
+ const targetGroup = nodeToGroup.get(edge.targets[0])
204
+
205
+ if (sourceGroup && targetGroup && sourceGroup !== targetGroup) {
206
+ const edgeKey = `${sourceGroup}->${targetGroup}`
207
+ if (!seenInterGroupEdges.has(edgeKey)) {
208
+ seenInterGroupEdges.add(edgeKey)
209
+ interGroupEdges.push({
210
+ id: `inter-${edgeKey}`,
211
+ sources: [sourceGroup],
212
+ targets: [targetGroup],
213
+ })
214
+ }
215
+ } else if ((!sourceGroup && targetGroup) || (sourceGroup && !targetGroup)) {
216
+ const source = sourceGroup || edge.sources[0]
217
+ const target = targetGroup || edge.targets[0]
218
+ const edgeKey = `${source}->${target}`
219
+ if (!seenInterGroupEdges.has(edgeKey)) {
220
+ seenInterGroupEdges.add(edgeKey)
221
+ interGroupEdges.push({
222
+ id: `inter-${edgeKey}`,
223
+ sources: [source],
224
+ targets: [target],
225
+ })
226
+ }
227
+ }
228
+ }
229
+
230
+ // Build and layout meta-graph
231
+ const metaChildren: ElkNode[] = [
232
+ ...groupLayouts.map(g => ({ id: g.groupId, width: g.width, height: g.height })),
233
+ ...ungroupedNodes.map(n => ({ id: n.id, width: n.width, height: n.height })),
234
+ ]
235
+
236
+ const metaGraph: ElkGraph = {
237
+ id: 'meta-root',
238
+ layoutOptions: elkOptionsGroupLayout,
239
+ children: metaChildren,
240
+ edges: interGroupEdges,
241
+ }
242
+
243
+ const metaLayoutResult = await elk.layout(metaGraph) as ElkLayoutResult
244
+
245
+ // Build position map
246
+ const groupPositions: Array<[string, { x: number; y: number }]> = []
247
+ for (const child of metaLayoutResult.children || []) {
248
+ groupPositions.push([child.id, { x: child.x || 0, y: child.y || 0 }])
249
+ }
250
+
251
+ const response: LayoutResponse = {
252
+ type: 'layout-result',
253
+ requestId,
254
+ groupLayouts,
255
+ ungroupedNodes,
256
+ groupPositions,
257
+ }
258
+
259
+ self.postMessage(response)
260
+ } catch (err) {
261
+ const errorMessage = err instanceof Error ? err.message : String(err)
262
+ const response: LayoutResponse = {
263
+ type: 'layout-result',
264
+ requestId,
265
+ groupLayouts: [],
266
+ ungroupedNodes: [],
267
+ groupPositions: [],
268
+ error: `Layout failed: ${errorMessage}`,
269
+ }
270
+ self.postMessage(response)
271
+ }
272
+ }
@@ -0,0 +1,129 @@
1
+ /*
2
+ * Topology visualization CSS for @skyhook/k8s-ui
3
+ * Provides node styling, icon colors, group borders, and layout utilities.
4
+ * Consumers must define the CSS variables below in their theme (light/dark).
5
+ *
6
+ * Required CSS variables:
7
+ * --topology-node-border, --topology-node-shadow
8
+ * --group-border-namespace, --group-border-app, --group-border-label
9
+ * --group-header-namespace, --group-header-app, --group-header-label
10
+ * --group-label-namespace, --group-label-app, --group-label-label
11
+ * --group-icon-namespace, --group-icon-app, --group-icon-label
12
+ * --topology-bg-dots
13
+ */
14
+
15
+ /* Topology node card styling */
16
+ .topology-node-card {
17
+ border: 1px solid var(--topology-node-border);
18
+ box-shadow: var(--topology-node-shadow);
19
+ }
20
+
21
+ /* Status bar via pseudo-element (saves one DOM element per node) */
22
+ .topology-node-status-bar::before {
23
+ content: '';
24
+ position: absolute;
25
+ left: 0;
26
+ top: 0;
27
+ bottom: 0;
28
+ width: 4px;
29
+ border-radius: 4px 0 0 4px;
30
+ }
31
+ .topology-node-status-healthy::before {
32
+ background-color: rgb(34 197 94); /* green-500 */
33
+ }
34
+ .topology-node-status-unknown::before {
35
+ background-color: rgb(100 116 139); /* slate-500 */
36
+ }
37
+
38
+ /* CSS-based topology icons (replaces Lucide SVGs - saves ~4000 DOM elements) */
39
+ .topology-icon {
40
+ display: inline-flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ width: 14px;
44
+ height: 14px;
45
+ border-radius: 3px;
46
+ font-size: 9px;
47
+ font-weight: 700;
48
+ color: white;
49
+ flex-shrink: 0;
50
+ background: #6b7280; /* gray-500 - default for unknown CRD kinds */
51
+ }
52
+ .topology-icon-internet { background: #3b82f6; border-radius: 50%; }
53
+ .topology-icon-ingress { background: #8b5cf6; }
54
+ .topology-icon-gateway { background: #8b5cf6; }
55
+ .topology-icon-httproute { background: #a78bfa; }
56
+ .topology-icon-grpcroute { background: #a78bfa; }
57
+ .topology-icon-tcproute { background: #a78bfa; }
58
+ .topology-icon-tlsroute { background: #a78bfa; }
59
+ .topology-icon-service { background: #3b82f6; border-radius: 50%; }
60
+ .topology-icon-deployment { background: #10b981; }
61
+ .topology-icon-rollout { background: #10b981; }
62
+ .topology-icon-daemonset { background: #14b8a6; }
63
+ .topology-icon-statefulset { background: #06b6d4; }
64
+ .topology-icon-replicaset { background: #22c55e; }
65
+ .topology-icon-pod { background: #84cc16; border-radius: 50%; }
66
+ .topology-icon-podgroup { background: #84cc16; border-radius: 50%; }
67
+ .topology-icon-configmap { background: #f59e0b; }
68
+ .topology-icon-secret { background: #ef4444; }
69
+ .topology-icon-horizontalpodautoscaler { background: #ec4899; }
70
+ .topology-icon-job { background: #a855f7; }
71
+ .topology-icon-cronjob { background: #a855f7; }
72
+ .topology-icon-persistentvolumeclaim { background: #06b6d4; }
73
+ .topology-icon-namespace { background: #6366f1; }
74
+ .topology-icon-application { background: #f97316; }
75
+ .topology-icon-kustomization { background: #0ea5e9; }
76
+ .topology-icon-helmrelease { background: #0ea5e9; }
77
+ .topology-icon-gitrepository { background: #14b8a6; }
78
+ .topology-icon-knativeservice { background: #d946ef; }
79
+ .topology-icon-knativeconfiguration { background: #c026d3; }
80
+ .topology-icon-knativerevision { background: #a855f7; }
81
+ .topology-icon-knativeroute { background: #d946ef; }
82
+ .topology-icon-broker { background: #c026d3; }
83
+ .topology-icon-trigger { background: #a855f7; }
84
+ .topology-icon-pingsource { background: #d946ef; }
85
+ .topology-icon-apiserversource { background: #c026d3; }
86
+ .topology-icon-containersource { background: #a855f7; }
87
+ .topology-icon-sinkbinding { background: #d946ef; }
88
+ .topology-icon-channel { background: #c026d3; }
89
+ .topology-icon-inmemorychannel { background: #c026d3; }
90
+ .topology-icon-subscription { background: #a855f7; }
91
+ .topology-icon-sequence { background: #d946ef; }
92
+ .topology-icon-parallel { background: #d946ef; }
93
+ .topology-icon-domainmapping { background: #d946ef; }
94
+ .topology-icon-serverlessservice { background: #a855f7; }
95
+ .topology-icon-node { background: #6366f1; }
96
+ .topology-icon-nodepool { background: #6366f1; }
97
+ .topology-icon-nodeclaim { background: #6366f1; }
98
+ .topology-icon-nodeclass { background: #6366f1; }
99
+
100
+ /* Background dots - uses CSS variable for theme awareness */
101
+ .react-flow__background pattern circle {
102
+ fill: var(--topology-bg-dots) !important;
103
+ }
104
+
105
+ /* Override default group node styling - we handle it in GroupNode component */
106
+ .react-flow__node-group {
107
+ background: transparent !important;
108
+ border: none !important;
109
+ box-shadow: none !important;
110
+ }
111
+
112
+ /* Group header scaling using CSS variable set by ViewportController */
113
+ .group-header-scaled {
114
+ transform: scale(var(--group-header-scale, 1));
115
+ transform-origin: top left;
116
+ }
117
+
118
+ /* Group container top adjustment based on header scale */
119
+ .group-container-adjusted {
120
+ top: var(--group-header-offset, 0px);
121
+ }
122
+
123
+ .react-flow__edge-path {
124
+ stroke-width: 2;
125
+ }
126
+
127
+ .react-flow__attribution {
128
+ display: none;
129
+ }