@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,151 @@
1
+ import { useState, useMemo, useCallback, useEffect, useRef } from 'react'
2
+ import type { VirtuosoHandle } from 'react-virtuoso'
3
+ import type { LogEntry } from './useLogBuffer'
4
+ import { stripAnsi, escapeRegExp } from '../../utils/log-format'
5
+
6
+ interface UseLogSearchReturn {
7
+ query: string
8
+ setQuery: (q: string) => void
9
+ isRegex: boolean
10
+ toggleRegex: () => void
11
+ isCaseSensitive: boolean
12
+ toggleCaseSensitive: () => void
13
+ isFilterMode: boolean
14
+ toggleFilterMode: () => void
15
+ matchCount: number
16
+ currentMatch: number
17
+ /** Indices into the entries array that match */
18
+ matchIndices: number[]
19
+ /** When filter mode is on, only matching entries */
20
+ filteredEntries: LogEntry[]
21
+ /** Error message when regex is invalid (null when valid) */
22
+ regexError: string | null
23
+ goToNext: () => void
24
+ goToPrev: () => void
25
+ isOpen: boolean
26
+ open: () => void
27
+ close: () => void
28
+ }
29
+
30
+ export function useLogSearch(
31
+ entries: LogEntry[],
32
+ virtuosoRef: React.RefObject<VirtuosoHandle | null>,
33
+ ): UseLogSearchReturn {
34
+ const [query, setQuery] = useState('')
35
+ const [isRegex, setIsRegex] = useState(false)
36
+ const [isCaseSensitive, setIsCaseSensitive] = useState(false)
37
+ const [isFilterMode, setIsFilterMode] = useState(false)
38
+ const [currentMatch, setCurrentMatch] = useState(0)
39
+ const [isOpen, setIsOpen] = useState(false)
40
+
41
+ const { matchIndices, regexError } = useMemo(() => {
42
+ if (!query) {
43
+ return { matchIndices: [] as number[], regexError: null }
44
+ }
45
+
46
+ try {
47
+ let pattern: RegExp
48
+ if (isRegex) {
49
+ pattern = new RegExp(query, isCaseSensitive ? 'g' : 'gi')
50
+ } else {
51
+ pattern = new RegExp(escapeRegExp(query), isCaseSensitive ? 'g' : 'gi')
52
+ }
53
+
54
+ const indices: number[] = []
55
+ for (let i = 0; i < entries.length; i++) {
56
+ const plain = stripAnsi(entries[i].content)
57
+ if (pattern.test(plain)) {
58
+ indices.push(i)
59
+ }
60
+ pattern.lastIndex = 0
61
+ }
62
+ return { matchIndices: indices, regexError: null }
63
+ } catch (e) {
64
+ return { matchIndices: [] as number[], regexError: e instanceof Error ? e.message : 'Invalid regex' }
65
+ }
66
+ }, [entries, query, isRegex, isCaseSensitive])
67
+
68
+ // Filtered entries for filter mode
69
+ const filteredEntries = useMemo(() => {
70
+ if (!isFilterMode || !query) return entries
71
+ const matchSet = new Set(matchIndices)
72
+ return entries.filter((_, i) => matchSet.has(i))
73
+ }, [entries, isFilterMode, query, matchIndices])
74
+
75
+ // Reset current match when search criteria change (but not when new entries arrive during streaming)
76
+ const prevCriteria = useRef({ query, isRegex, isCaseSensitive })
77
+ useEffect(() => {
78
+ if (
79
+ prevCriteria.current.query !== query ||
80
+ prevCriteria.current.isRegex !== isRegex ||
81
+ prevCriteria.current.isCaseSensitive !== isCaseSensitive
82
+ ) {
83
+ setCurrentMatch(0)
84
+ prevCriteria.current = { query, isRegex, isCaseSensitive }
85
+ }
86
+ }, [query, isRegex, isCaseSensitive])
87
+
88
+ const scrollToMatch = useCallback((matchIdx: number) => {
89
+ if (matchIdx < 0 || matchIdx >= matchIndices.length) return
90
+ if (isFilterMode) {
91
+ // In filter mode, match index maps directly to filtered list index
92
+ virtuosoRef.current?.scrollToIndex({
93
+ index: matchIdx,
94
+ align: 'center',
95
+ behavior: 'smooth',
96
+ })
97
+ } else {
98
+ const entryIndex = matchIndices[matchIdx]
99
+ virtuosoRef.current?.scrollToIndex({
100
+ index: entryIndex,
101
+ align: 'center',
102
+ behavior: 'smooth',
103
+ })
104
+ }
105
+ }, [matchIndices, isFilterMode, virtuosoRef])
106
+
107
+ const goToNext = useCallback(() => {
108
+ if (matchIndices.length === 0) return
109
+ const next = (currentMatch + 1) % matchIndices.length
110
+ setCurrentMatch(next)
111
+ scrollToMatch(next)
112
+ }, [currentMatch, matchIndices.length, scrollToMatch])
113
+
114
+ const goToPrev = useCallback(() => {
115
+ if (matchIndices.length === 0) return
116
+ const prev = (currentMatch - 1 + matchIndices.length) % matchIndices.length
117
+ setCurrentMatch(prev)
118
+ scrollToMatch(prev)
119
+ }, [currentMatch, matchIndices.length, scrollToMatch])
120
+
121
+ const toggleRegex = useCallback(() => setIsRegex(p => !p), [])
122
+ const toggleCaseSensitive = useCallback(() => setIsCaseSensitive(p => !p), [])
123
+ const toggleFilterMode = useCallback(() => setIsFilterMode(p => !p), [])
124
+
125
+ const open = useCallback(() => setIsOpen(true), [])
126
+ const close = useCallback(() => {
127
+ setIsOpen(false)
128
+ setQuery('')
129
+ }, [])
130
+
131
+ return {
132
+ query,
133
+ setQuery,
134
+ isRegex,
135
+ toggleRegex,
136
+ isCaseSensitive,
137
+ toggleCaseSensitive,
138
+ isFilterMode,
139
+ toggleFilterMode,
140
+ matchCount: matchIndices.length,
141
+ currentMatch,
142
+ matchIndices,
143
+ filteredEntries,
144
+ regexError,
145
+ goToNext,
146
+ goToPrev,
147
+ isOpen,
148
+ open,
149
+ close,
150
+ }
151
+ }
@@ -0,0 +1,61 @@
1
+ import { useState, useRef, useCallback, useEffect } from 'react'
2
+ import { handleSSEError } from '../../utils/log-format'
3
+
4
+ export interface LogStreamHandlers {
5
+ /** Called when stream connects with parsed event data. setIsStreaming(true) is called automatically. */
6
+ onConnected?: (data: unknown) => void
7
+ /** Called for each log event with parsed event data */
8
+ onLog: (data: unknown) => void
9
+ }
10
+
11
+ /**
12
+ * Manages an SSE log stream: EventSource lifecycle, isStreaming state, cleanup.
13
+ * Callers provide a factory function that creates the EventSource with current params.
14
+ */
15
+ export function useLogStream() {
16
+ const [isStreaming, setIsStreaming] = useState(false)
17
+ const eventSourceRef = useRef<EventSource | null>(null)
18
+
19
+ const stopStreaming = useCallback(() => {
20
+ eventSourceRef.current?.close()
21
+ eventSourceRef.current = null
22
+ setIsStreaming(false)
23
+ }, [])
24
+
25
+ const startStreaming = useCallback((
26
+ create: () => EventSource,
27
+ handlers: LogStreamHandlers,
28
+ errorContext = 'Log stream error',
29
+ ) => {
30
+ eventSourceRef.current?.close()
31
+ const es = create()
32
+
33
+ es.addEventListener('connected', (event) => {
34
+ setIsStreaming(true)
35
+ if (handlers.onConnected) {
36
+ try { handlers.onConnected(JSON.parse((event as MessageEvent).data)) } catch (e) {
37
+ console.error('Failed to parse connected event:', e)
38
+ }
39
+ }
40
+ })
41
+
42
+ es.addEventListener('log', (event) => {
43
+ try { handlers.onLog(JSON.parse((event as MessageEvent).data)) } catch (e) {
44
+ console.error('Failed to parse log event:', e)
45
+ }
46
+ })
47
+
48
+ es.addEventListener('end', () => setIsStreaming(false))
49
+
50
+ es.addEventListener('error', (event) => {
51
+ handleSSEError(event, errorContext, () => { setIsStreaming(false); es.close() })
52
+ })
53
+
54
+ eventSourceRef.current = es
55
+ }, [])
56
+
57
+ // Cleanup on unmount
58
+ useEffect(() => () => { eventSourceRef.current?.close() }, [])
59
+
60
+ return { isStreaming, startStreaming, stopStreaming }
61
+ }