@skyhook-io/k8s-ui 1.1.1 → 1.2.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 (41) hide show
  1. package/package.json +6 -2
  2. package/src/components/dock/BottomDock.tsx +14 -15
  3. package/src/components/dock/DockContext.tsx +40 -1
  4. package/src/components/dock/LocalTerminalTab.tsx +241 -0
  5. package/src/components/dock/NodeTerminalTab.tsx +129 -0
  6. package/src/components/dock/TerminalTab.tsx +1 -1
  7. package/src/components/dock/index.ts +2 -0
  8. package/src/components/gitops/GitOpsStatusBadge.tsx +18 -67
  9. package/src/components/logs/LogCore.tsx +30 -4
  10. package/src/components/logs/StructuredLogLine.tsx +168 -0
  11. package/src/components/logs/index.ts +1 -1
  12. package/src/components/logs/useLogBuffer.ts +16 -10
  13. package/src/components/resources/ResourcesView.tsx +136 -24
  14. package/src/components/resources/renderers/ContourHTTPProxyRenderer.tsx +207 -0
  15. package/src/components/resources/renderers/PodRenderer.tsx +164 -8
  16. package/src/components/resources/renderers/contour-cells.tsx +48 -0
  17. package/src/components/resources/renderers/index.ts +2 -0
  18. package/src/components/resources/renderers/trivy-shared.tsx +9 -25
  19. package/src/components/resources/resource-utils-contour.ts +34 -0
  20. package/src/components/resources/resource-utils.ts +91 -0
  21. package/src/components/shared/ResourceActionsBar.tsx +135 -2
  22. package/src/components/shared/ResourceRendererDispatch.tsx +23 -5
  23. package/src/components/timeline/shared.tsx +8 -10
  24. package/src/components/topology/K8sResourceNode.tsx +1 -0
  25. package/src/components/topology/TopologyFilterSidebar.tsx +3 -0
  26. package/src/components/topology/layout.ts +1 -0
  27. package/src/components/topology/topology.css +1 -0
  28. package/src/components/ui/CodeViewer.tsx +1 -2
  29. package/src/components/ui/ForceDeleteConfirmDialog.tsx +84 -10
  30. package/src/components/ui/Toast.tsx +5 -5
  31. package/src/components/ui/drawer-components.tsx +28 -22
  32. package/src/components/workload/WorkloadView.tsx +11 -3
  33. package/src/theme/index.ts +3 -0
  34. package/src/theme/tailwind-theme.css +61 -0
  35. package/src/theme/variables.css +121 -0
  36. package/src/types/core.ts +12 -0
  37. package/src/utils/animation.ts +1 -1
  38. package/src/utils/badge-colors.ts +158 -123
  39. package/src/utils/log-format.ts +127 -35
  40. package/src/utils/resource-hierarchy.ts +5 -0
  41. package/src/utils/resource-icons.ts +3 -0
@@ -17,7 +17,7 @@ import {
17
17
  X,
18
18
  BarChart3,
19
19
  } from 'lucide-react'
20
- import type { TimelineEvent, ResourceRef, Relationships, SelectedResource } from '../../types'
20
+ import type { TimelineEvent, ResourceRef, Relationships, SelectedResource, ResolvedEnvFrom } from '../../types'
21
21
  import type { NavigateToResource } from '../../utils/navigation'
22
22
  import { refToSelectedResource, pluralToKind } from '../../utils/navigation'
23
23
  import { isChangeEvent, isHistoricalEvent } from '../../types'
@@ -125,10 +125,10 @@ interface WorkloadViewProps {
125
125
  // ── ResourceActionsBar props (passed through) ────────────────────────────
126
126
  /** All props for the actions bar (forwarded as-is) */
127
127
  actionsBarProps?: Record<string, any>
128
-
129
- // ── Renderer overrides ──────────────────────────────────────────────────
130
128
  /** Platform-specific renderer overrides (e.g. with hooks for metrics, exec, port-forward) */
131
129
  rendererOverrides?: RendererOverrides
130
+ /** Resolved ConfigMap/Secret data for envFrom expansion in PodRenderer */
131
+ resolvedEnvFrom?: ResolvedEnvFrom
132
132
  }
133
133
 
134
134
  export function WorkloadView({
@@ -170,6 +170,8 @@ export function WorkloadView({
170
170
  actionsBarProps,
171
171
  // Renderer overrides
172
172
  rendererOverrides,
173
+ // Pod env expansion
174
+ resolvedEnvFrom,
173
175
  }: WorkloadViewProps) {
174
176
  // Normalize kind: URL has plural lowercase, internal logic uses singular PascalCase
175
177
  const kind = pluralToKind(kindProp)
@@ -441,6 +443,8 @@ export function WorkloadView({
441
443
  onSaveSecretValue={canUpdateSecrets ? handleSaveSecretValue : undefined}
442
444
  isSavingSecret={isUpdatingResource}
443
445
  rendererOverrides={rendererOverrides}
446
+ resolvedEnvFrom={resolvedEnvFrom}
447
+ renderMetrics={renderMetricsTab}
444
448
  />
445
449
  )}
446
450
  </div>
@@ -580,6 +584,7 @@ export function WorkloadView({
580
584
  onOpenLogs={handleOpenLogs}
581
585
  onSwitchToTimeline={() => handleSetTab('timeline')}
582
586
  rendererOverrides={rendererOverrides}
587
+ resolvedEnvFrom={resolvedEnvFrom}
583
588
  />
584
589
  )}
585
590
  {activeTab === 'timeline' && (
@@ -1062,6 +1067,7 @@ function InfoTab({
1062
1067
  onOpenLogs,
1063
1068
  onSwitchToTimeline,
1064
1069
  rendererOverrides,
1070
+ resolvedEnvFrom,
1065
1071
  }: {
1066
1072
  resource: any
1067
1073
  selectedResource: SelectedResource
@@ -1075,6 +1081,7 @@ function InfoTab({
1075
1081
  onOpenLogs?: (podName: string, containerName: string) => void
1076
1082
  onSwitchToTimeline?: () => void
1077
1083
  rendererOverrides?: RendererOverrides
1084
+ resolvedEnvFrom?: ResolvedEnvFrom
1078
1085
  }) {
1079
1086
  if (isLoading) {
1080
1087
  return (
@@ -1108,6 +1115,7 @@ function InfoTab({
1108
1115
  showMetrics={false}
1109
1116
  onOpenLogs={onOpenLogs}
1110
1117
  rendererOverrides={rendererOverrides}
1118
+ resolvedEnvFrom={resolvedEnvFrom}
1111
1119
  eventsHint={onSwitchToTimeline && (
1112
1120
  <button
1113
1121
  onClick={onSwitchToTimeline}
@@ -0,0 +1,3 @@
1
+ // Theme barrel export
2
+ // CSS files are imported directly: @import "@skyhook-io/k8s-ui/theme/variables.css"
3
+ // This file exists for consumers that want a JS entry point for the theme module.
@@ -0,0 +1,61 @@
1
+ /*
2
+ * @skyhook-io/k8s-ui Tailwind Theme
3
+ *
4
+ * Maps CSS variables to Tailwind v4 @theme tokens.
5
+ * Enables utility classes: bg-theme-surface, text-theme-text-primary, border-accent, etc.
6
+ * Import after variables.css.
7
+ */
8
+
9
+ @theme inline {
10
+ /* Backgrounds */
11
+ --color-theme-base: var(--bg-base);
12
+ --color-theme-surface: var(--bg-surface);
13
+ --color-theme-elevated: var(--bg-elevated);
14
+ --color-theme-hover: var(--bg-hover);
15
+ --color-theme-active: var(--bg-active);
16
+
17
+ /* Text */
18
+ --color-theme-text-primary: var(--text-primary);
19
+ --color-theme-text-secondary: var(--text-secondary);
20
+ --color-theme-text-tertiary: var(--text-tertiary);
21
+ --color-theme-text-disabled: var(--text-disabled);
22
+
23
+ /* Borders */
24
+ --color-theme-border: var(--border-default);
25
+ --color-theme-border-light: var(--border-light);
26
+ --color-theme-border-subtle: var(--border-subtle);
27
+
28
+ /* Accent */
29
+ --color-accent: var(--accent);
30
+ --color-accent-light: var(--accent-light);
31
+ --color-accent-muted: var(--accent-muted);
32
+ --color-accent-text: var(--accent-text);
33
+
34
+ /* Skyhook brand */
35
+ --color-skyhook: #2D7AFF;
36
+ --color-skyhook-50: #E6F0FF;
37
+ --color-skyhook-100: #CCE0FF;
38
+ --color-skyhook-200: #99C2FF;
39
+ --color-skyhook-300: #66A3FF;
40
+ --color-skyhook-400: #3385FF;
41
+ --color-skyhook-500: #2D7AFF;
42
+ --color-skyhook-600: #0052CC;
43
+ --color-skyhook-700: #003D99;
44
+ --color-skyhook-800: #002966;
45
+ --color-skyhook-900: #001433;
46
+
47
+ /* K8s resource type colors */
48
+ --color-k8s-internet: #2D7AFF;
49
+ --color-k8s-ingress: #8b5cf6;
50
+ --color-k8s-service: #3b82f6;
51
+ --color-k8s-deployment: #10b981;
52
+ --color-k8s-daemonset: #14b8a6;
53
+ --color-k8s-statefulset: #06b6d4;
54
+ --color-k8s-replicaset: #22c55e;
55
+ --color-k8s-pod: #84cc16;
56
+ --color-k8s-configmap: #f59e0b;
57
+ --color-k8s-secret: #ef4444;
58
+ --color-k8s-hpa: #ec4899;
59
+ --color-k8s-job: #a855f7;
60
+ --color-k8s-cronjob: #d946ef;
61
+ }
@@ -0,0 +1,121 @@
1
+ /*
2
+ * @skyhook-io/k8s-ui Theme Variables
3
+ *
4
+ * Single source of truth for the theme contract.
5
+ * Uses light-dark() for dual-value definitions.
6
+ * Consumers @import this file, then override any variables via CSS cascade.
7
+ *
8
+ * Toggle mechanism:
9
+ * document.documentElement.classList.toggle('dark', isDark)
10
+ * document.documentElement.style.colorScheme = isDark ? 'dark' : 'light'
11
+ */
12
+
13
+ :root {
14
+ color-scheme: light dark;
15
+
16
+ /* ── Brand ── */
17
+ --color-brand: #2D7AFF;
18
+ --color-brand-light: light-dark(#1A5FCC, #5A9AFF);
19
+
20
+ /* ── Semantic status (theme-independent) ── */
21
+ --color-success: #22C55E;
22
+ --color-success-light: #4ADE80;
23
+ --color-success-dark: #16A34A;
24
+ --color-warning: #F59E0B;
25
+ --color-warning-light: #FBBF24;
26
+ --color-warning-dark: #D97706;
27
+ --color-error: #EF4444;
28
+ --color-error-light: #F87171;
29
+ --color-error-dark: #DC2626;
30
+ --color-info: #3B82F6;
31
+
32
+ /* ── Backgrounds ── */
33
+ --bg-base: light-dark(#f7f9fc, #0c1425);
34
+ --bg-surface: light-dark(#ffffff, #162033);
35
+ --bg-elevated: light-dark(#edf2f8, #1e2d45);
36
+ --bg-hover: light-dark(#e2e8f0, #2a3d58);
37
+ --bg-active: light-dark(#dbeafe, #1e3a5f);
38
+
39
+ /* ── Text ── */
40
+ --text-primary: light-dark(#0f172a, #f8fafc);
41
+ --text-secondary: light-dark(#475569, #cbd5e1);
42
+ --text-tertiary: light-dark(#64748b, #94a3b8);
43
+ --text-disabled: light-dark(#94a3b8, #64748b);
44
+
45
+ /* ── Borders ── */
46
+ --border-default: light-dark(#e2e8f0, #1e2d45);
47
+ --border-light: light-dark(#cbd5e1, #2a3d58);
48
+ --border-subtle: light-dark(rgba(0, 0, 0, 0.06), rgba(255, 255, 255, 0.02));
49
+ --border-focus: var(--color-brand);
50
+
51
+ /* ── Accent ── */
52
+ --accent: var(--color-brand);
53
+ --accent-light: var(--color-brand-light);
54
+ --accent-muted: light-dark(rgba(45, 122, 255, 0.1), rgba(45, 122, 255, 0.2));
55
+ --accent-text: light-dark(#1d4ed8, #93c5fd);
56
+
57
+ /* ── Shadows (light defaults — can't use light-dark() for comma-separated values) ── */
58
+ --shadow-sm: 0 1px 3px rgba(0,0,0,0.04), 0 1px 2px rgba(0,0,0,0.02);
59
+ --shadow-md: 0 4px 12px -2px rgba(0,0,0,0.06), 0 2px 4px rgba(0,0,0,0.03);
60
+ --shadow-lg: 0 12px 32px -6px rgba(0,0,0,0.08), 0 4px 8px rgba(0,0,0,0.04);
61
+
62
+ /* ── Topology ── */
63
+ --topology-node-border: light-dark(rgba(0, 0, 0, 0.10), rgba(255, 255, 255, 0.08));
64
+ --topology-node-shadow: 0 2px 6px rgba(0,0,0,0.05), 0 6px 16px rgba(0,0,0,0.04);
65
+ --topology-bg-dots: light-dark(rgba(148, 163, 184, 0.25), #1e2d45);
66
+
67
+ /* Topology edge colors (theme-independent identity colors) */
68
+ --edge-routes-to: #22c55e;
69
+ --edge-exposes: #3b82f6;
70
+ --edge-manages: #64748b;
71
+ --edge-configures: #f59e0b;
72
+ --edge-uses: #ec4899;
73
+
74
+ /* ── Group styling ── */
75
+ --group-border-namespace: light-dark(rgba(59, 130, 246, 0.3), rgba(59, 130, 246, 0.4));
76
+ --group-border-app: light-dark(rgba(16, 185, 129, 0.3), rgba(16, 185, 129, 0.4));
77
+ --group-border-label: light-dark(rgba(245, 158, 11, 0.3), rgba(245, 158, 11, 0.4));
78
+
79
+ --group-header-namespace: light-dark(rgba(59, 130, 246, 0.15), rgba(59, 130, 246, 0.2));
80
+ --group-header-app: light-dark(rgba(16, 185, 129, 0.15), rgba(16, 185, 129, 0.2));
81
+ --group-header-label: light-dark(rgba(245, 158, 11, 0.15), rgba(245, 158, 11, 0.2));
82
+
83
+ --group-label-namespace: light-dark(#1d4ed8, #93c5fd);
84
+ --group-label-app: light-dark(#047857, #6ee7b7);
85
+ --group-label-label: light-dark(#b45309, #fcd34d);
86
+
87
+ --group-icon-namespace: light-dark(#2563eb, #60a5fa);
88
+ --group-icon-app: light-dark(#059669, #34d399);
89
+ --group-icon-label: light-dark(#d97706, #fbbf24);
90
+
91
+ /* ── ANSI terminal colors (theme-aware for log viewer) ── */
92
+ --ansi-black: light-dark(#3b3b3b, #4c4c4c);
93
+ --ansi-red: light-dark(#cd3131, #cd3131);
94
+ --ansi-green: light-dark(#00a854, #0dbc79);
95
+ --ansi-yellow: light-dark(#b8860b, #e5e510);
96
+ --ansi-blue: light-dark(#2472c8, #2472c8);
97
+ --ansi-magenta: light-dark(#bc3fbc, #bc3fbc);
98
+ --ansi-cyan: light-dark(#11a8cd, #11a8cd);
99
+ --ansi-white: light-dark(#e5e5e5, #e5e5e5);
100
+ --ansi-bright-black: light-dark(#555555, #767676);
101
+ --ansi-bright-red: light-dark(#f14c4c, #f14c4c);
102
+ --ansi-bright-green: light-dark(#17b96a, #23d18b);
103
+ --ansi-bright-yellow: light-dark(#c49700, #f5f543);
104
+ --ansi-bright-blue: light-dark(#3b8eea, #3b8eea);
105
+ --ansi-bright-magenta: light-dark(#d670d6, #d670d6);
106
+ --ansi-bright-cyan: light-dark(#29b8db, #29b8db);
107
+ --ansi-bright-white: light-dark(#e5e5e5, #e5e5e5);
108
+
109
+ /* ── Scrollbar ── */
110
+ --scrollbar-track: light-dark(#f1f5f9, #162033);
111
+ --scrollbar-thumb: light-dark(#cbd5e1, #2a3d58);
112
+ --scrollbar-thumb-hover: light-dark(#94a3b8, #3d5474);
113
+ }
114
+
115
+ /* Dark overrides for comma-separated values that can't use light-dark() */
116
+ .dark {
117
+ --shadow-sm: 0 1px 3px rgba(0,0,0,0.2), 0 1px 2px rgba(0,0,0,0.1);
118
+ --shadow-md: 0 4px 12px -2px rgba(0,0,0,0.25), 0 2px 4px rgba(0,0,0,0.1);
119
+ --shadow-lg: 0 12px 32px -6px rgba(0,0,0,0.3), 0 4px 8px rgba(0,0,0,0.1);
120
+ --topology-node-shadow: 0 2px 6px rgba(0,0,0,0.2), 0 6px 16px rgba(0,0,0,0.15);
121
+ }
package/src/types/core.ts CHANGED
@@ -25,11 +25,13 @@ export interface ResourcePermissions {
25
25
  // Feature capabilities based on RBAC permissions
26
26
  export interface Capabilities {
27
27
  exec: boolean // Terminal feature (pods/exec)
28
+ localTerminal: boolean // Local terminal available (not in-cluster, not disabled)
28
29
  logs: boolean // Log viewer (pods/log)
29
30
  portForward: boolean // Port forwarding (pods/portforward)
30
31
  secrets: boolean // List secrets
31
32
  secretsUpdate: boolean // Update secrets (inline editing)
32
33
  helmWrite: boolean // Helm write operations (install, upgrade, rollback, uninstall, apply values)
34
+ nodeWrite: boolean // Node write operations (cordon, uncordon, drain)
33
35
  mcpEnabled: boolean // MCP server is running
34
36
  resources?: ResourcePermissions // Per-resource-type permissions
35
37
  }
@@ -95,6 +97,7 @@ export type CoreNodeKind =
95
97
  | 'ServersTransportTCP' // Traefik ServersTransportTCP
96
98
  | 'TLSOption' // Traefik TLSOption
97
99
  | 'TLSStore' // Traefik TLSStore
100
+ | 'HTTPProxy' // Contour HTTPProxy
98
101
 
99
102
  // NodeKind can be a core kind or any arbitrary CRD kind string
100
103
  export type NodeKind = CoreNodeKind | (string & {})
@@ -328,6 +331,14 @@ export interface SelectedResource {
328
331
  group?: string // API group for CRDs (e.g., 'metrics.k8s.io')
329
332
  }
330
333
 
334
+ // Resolved envFrom ConfigMap/Secret data for pod env var expansion
335
+ export interface ResolvedEnvFromEntry {
336
+ keys: string[]
337
+ values: Record<string, string>
338
+ isSecret: boolean
339
+ }
340
+ export type ResolvedEnvFrom = Record<string, ResolvedEnvFromEntry>
341
+
331
342
  // Resource reference (for relationships)
332
343
  export interface ResourceRef {
333
344
  kind: string
@@ -744,6 +755,7 @@ export interface TrafficHelmChartInfo {
744
755
  repoUrl: string
745
756
  chartName: string
746
757
  version?: string
758
+ defaultValues?: Record<string, unknown>
747
759
  }
748
760
 
749
761
  // Recommendation for installing a traffic source
@@ -18,7 +18,7 @@ export const CSS_EASE = 'cubic-bezier(0.32, 0.72, 0, 1)'
18
18
  /** Standard UI transitions: overlays, panels, toasts */
19
19
  export const DURATION_NORMAL = 300
20
20
  /** Dock height, subtle layout shifts */
21
- export const DURATION_DOCK = 250
21
+ export const DURATION_DOCK = 150
22
22
  /** Toast exit animation */
23
23
  export const DURATION_TOAST_EXIT = 200
24
24