@skyhook-io/radar-app 0.2.2 → 0.3.1

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 (177) hide show
  1. package/README.md +7 -1
  2. package/package.json +33 -25
  3. package/src/App.tsx +1449 -382
  4. package/src/RadarApp.tsx +132 -19
  5. package/src/api/apiResources.ts +1 -1
  6. package/src/api/client.argoResourceSync.test.ts +69 -0
  7. package/src/api/client.delta.test.ts +89 -0
  8. package/src/api/client.deltaSync.test.ts +216 -0
  9. package/src/api/client.metrics.test.ts +106 -0
  10. package/src/api/client.rightsizing.test.ts +32 -0
  11. package/src/api/client.ts +2730 -271
  12. package/src/api/client.yaml.test.ts +45 -0
  13. package/src/api/diagnose.ts +289 -0
  14. package/src/api/quotas.ts +16 -0
  15. package/src/api/rbac.ts +57 -0
  16. package/src/api/timelineSource.test.ts +217 -0
  17. package/src/api/timelineSource.ts +582 -0
  18. package/src/components/ConnectionErrorView.tsx +186 -70
  19. package/src/components/ContextSwitcher.tsx +63 -18
  20. package/src/components/DebugOverlay.tsx +5 -3
  21. package/src/components/NamespaceSwitcher.tsx +41 -0
  22. package/src/components/UserMenu.tsx +69 -21
  23. package/src/components/applications/ApplicationsView.tsx +936 -0
  24. package/src/components/audit/AuditSettingsDialog.tsx +79 -17
  25. package/src/components/audit/AuditView.tsx +65 -62
  26. package/src/components/compare/CompareViewRoute.tsx +124 -0
  27. package/src/components/compare/useCompareCandidates.ts +27 -0
  28. package/src/components/compare/useCompareLauncher.tsx +79 -0
  29. package/src/components/cost/ApplicationCostTab.test.ts +204 -0
  30. package/src/components/cost/ApplicationCostTab.tsx +571 -0
  31. package/src/components/cost/CostTrendChart.tsx +106 -75
  32. package/src/components/cost/CostView.test.ts +12 -0
  33. package/src/components/cost/CostView.tsx +507 -223
  34. package/src/components/cost/CostViewTabs.test.tsx +21 -0
  35. package/src/components/cost/CostViewTabs.tsx +40 -0
  36. package/src/components/cost/CurrentAllocationUse.test.ts +21 -0
  37. package/src/components/cost/CurrentAllocationUse.tsx +126 -0
  38. package/src/components/cost/WorkloadCostTab.test.ts +153 -0
  39. package/src/components/cost/WorkloadCostTab.tsx +372 -0
  40. package/src/components/cost/cloud-console.test.ts +39 -0
  41. package/src/components/cost/cloud-console.ts +81 -0
  42. package/src/components/cost/errors.ts +8 -0
  43. package/src/components/cost/format.test.ts +27 -0
  44. package/src/components/cost/format.ts +46 -0
  45. package/src/components/cost/kinds.ts +5 -0
  46. package/src/components/curl/ServiceCurlButton.tsx +445 -0
  47. package/src/components/diagnose/AISettings.tsx +147 -0
  48. package/src/components/diagnose/DiagnoseContext.tsx +495 -0
  49. package/src/components/diagnose/DiagnoseSurface.tsx +394 -0
  50. package/src/components/diagnose/Home.tsx +163 -0
  51. package/src/components/diagnose/InvestigationView.tsx +622 -0
  52. package/src/components/diagnose/LocalDiagnoseAction.tsx +162 -0
  53. package/src/components/diagnose/launch.ts +65 -0
  54. package/src/components/diagnose/parts.tsx +1756 -0
  55. package/src/components/dock/BottomDock.tsx +2 -3
  56. package/src/components/dock/DockContext.tsx +1 -0
  57. package/src/components/dock/TerminalTab.tsx +1 -1
  58. package/src/components/dock/WorkloadLogsTab.tsx +21 -5
  59. package/src/components/dock/index.ts +1 -1
  60. package/src/components/execution/BatchExecutionView.test.ts +170 -0
  61. package/src/components/execution/BatchExecutionView.tsx +1329 -0
  62. package/src/components/execution/batch-run-actions.test.ts +48 -0
  63. package/src/components/execution/batch-run-actions.ts +24 -0
  64. package/src/components/execution/batch-timeline.test.ts +57 -0
  65. package/src/components/execution/batch-timeline.ts +46 -0
  66. package/src/components/execution/execution-definition.test.ts +208 -0
  67. package/src/components/execution/execution-definition.ts +245 -0
  68. package/src/components/gitops/ArgoResourceDiffLoader.tsx +23 -0
  69. package/src/components/gitops/GitOpsView.tsx +1042 -0
  70. package/src/components/gitops/RevisionMetaChip.tsx +63 -0
  71. package/src/components/helm/ChartBrowser.tsx +87 -31
  72. package/src/components/helm/HelmCompareRoute.tsx +1341 -0
  73. package/src/components/helm/HelmReleaseDrawer.test.ts +17 -0
  74. package/src/components/helm/HelmReleaseDrawer.tsx +1073 -102
  75. package/src/components/helm/HelmView.tsx +237 -96
  76. package/src/components/helm/InstallWizard.tsx +94 -38
  77. package/src/components/helm/ManifestDiffViewer.tsx +8 -27
  78. package/src/components/helm/OwnedResources.tsx +34 -59
  79. package/src/components/helm/RevisionHistory.tsx +52 -3
  80. package/src/components/helm/RoleGatedPanel.tsx +3 -3
  81. package/src/components/helm/TrackChartSourceDialog.tsx +185 -0
  82. package/src/components/helm/ValuesDiffPreview.tsx +17 -7
  83. package/src/components/helm/ValuesViewer.tsx +49 -53
  84. package/src/components/helm/helm-utils.ts +4 -0
  85. package/src/components/home/ActivitySummary.tsx +4 -1
  86. package/src/components/home/ClusterHealthCard.tsx +56 -42
  87. package/src/components/home/CostCard.tsx +21 -36
  88. package/src/components/home/GitOpsControllersCard.tsx +110 -0
  89. package/src/components/home/HelmSummary.tsx +3 -1
  90. package/src/components/home/HomeView.tsx +339 -105
  91. package/src/components/home/MCPSetupDialog.tsx +29 -87
  92. package/src/components/home/TrafficSummary.tsx +2 -2
  93. package/src/components/home/mcpToolCatalog.ts +333 -0
  94. package/src/components/issues/IssuesPane.tsx +151 -0
  95. package/src/components/logs/LogsViewer.tsx +4 -1
  96. package/src/components/logs/ScheduledWorkloadLogsViewer.tsx +135 -0
  97. package/src/components/logs/WorkloadLogsViewer.tsx +4 -1
  98. package/src/components/nav/PrimaryNavRail.tsx +285 -0
  99. package/src/components/portforward/PortForwardButton.tsx +118 -47
  100. package/src/components/portforward/PortForwardManager.tsx +253 -131
  101. package/src/components/resource/HPACharts.tsx +237 -0
  102. package/src/components/resource/PVCUsageBar.tsx +59 -0
  103. package/src/components/resource/PrometheusCharts.tsx +160 -584
  104. package/src/components/resource/PrometheusChartsGrid.tsx +270 -0
  105. package/src/components/resource/RestartChart.tsx +133 -0
  106. package/src/components/resource/RightsizingStrip.test.ts +109 -0
  107. package/src/components/resource/RightsizingStrip.tsx +363 -0
  108. package/src/components/resource-drawer/ResourceDrawer.tsx +3 -1
  109. package/src/components/resources/CompositeRenderer.tsx +101 -0
  110. package/src/components/resources/ImageFilesystemModal.tsx +19 -12
  111. package/src/components/resources/PodFilesystemModal.tsx +6 -5
  112. package/src/components/resources/ResourceDetailDrawer.tsx +13 -3
  113. package/src/components/resources/ResourcesView.tsx +194 -17
  114. package/src/components/resources/renderers/CronWorkflowRenderer.tsx +1 -0
  115. package/src/components/resources/renderers/HPARenderer.tsx +20 -1
  116. package/src/components/resources/renderers/NamespaceRenderer.tsx +31 -0
  117. package/src/components/resources/renderers/NodeRenderer.tsx +10 -4
  118. package/src/components/resources/renderers/PVCRenderer.tsx +19 -1
  119. package/src/components/resources/renderers/PodRenderer.tsx +30 -6
  120. package/src/components/resources/renderers/RoleBindingRenderer.tsx +45 -1
  121. package/src/components/resources/renderers/RoleRenderer.tsx +27 -1
  122. package/src/components/resources/renderers/ServiceAccountRenderer.tsx +28 -1
  123. package/src/components/resources/renderers/ServiceRenderer.tsx +81 -8
  124. package/src/components/resources/renderers/WorkloadRenderer.tsx +51 -4
  125. package/src/components/resources/renderers/index.ts +2 -0
  126. package/src/components/resources/resource-utils.ts +2 -1
  127. package/src/components/rightsizing/RightsizingScanView.tsx +938 -0
  128. package/src/components/rightsizing/copy.test.ts +56 -0
  129. package/src/components/rightsizing/model.test.ts +227 -0
  130. package/src/components/rightsizing/model.ts +158 -0
  131. package/src/components/rightsizing/presentation.test.ts +104 -0
  132. package/src/components/rightsizing/presentation.ts +94 -0
  133. package/src/components/settings/MyPermissionsDialog.tsx +241 -0
  134. package/src/components/settings/SettingsDialog.tsx +1505 -165
  135. package/src/components/shared/CreateResourceDialog.tsx +9 -2
  136. package/src/components/shared/LargeClusterNamespacePicker.tsx +3 -3
  137. package/src/components/timeline/LocalTimelineScrubber.tsx +212 -0
  138. package/src/components/timeline/RetainedTimelineScrubber.tsx +311 -0
  139. package/src/components/timeline/TimelineList.tsx +86 -13
  140. package/src/components/timeline/TimelineSwimlanes.tsx +9 -1299
  141. package/src/components/timeline/TimelineView.tsx +873 -24
  142. package/src/components/timeline/TimelineView.urlparams.test.ts +335 -0
  143. package/src/components/traffic/TrafficFilterSidebar.tsx +10 -45
  144. package/src/components/traffic/TrafficFlowList.tsx +29 -15
  145. package/src/components/traffic/TrafficGraph.tsx +42 -24
  146. package/src/components/traffic/TrafficView.tsx +32 -19
  147. package/src/components/ui/CommandPalette.tsx +8 -215
  148. package/src/components/ui/DiagnosticsOverlay.tsx +219 -9
  149. package/src/components/ui/Markdown.tsx +3 -3
  150. package/src/components/ui/Omnibar.tsx +602 -0
  151. package/src/components/ui/RadarOmnibar.tsx +52 -0
  152. package/src/components/ui/SearchSyntaxHelp.tsx +89 -0
  153. package/src/components/ui/ShortcutHelpOverlay.tsx +3 -2
  154. package/src/components/ui/UpdateNotification.tsx +48 -36
  155. package/src/components/ui/command-items.ts +178 -0
  156. package/src/components/workload/WorkloadView.tsx +1342 -158
  157. package/src/context/ConnectionContext.tsx +146 -21
  158. package/src/context/DiagnoseCustomization.tsx +93 -0
  159. package/src/context/NavCustomization.tsx +75 -0
  160. package/src/context/TimelineSource.tsx +50 -0
  161. package/src/contexts/CapabilitiesContext.tsx +32 -8
  162. package/src/filter/FilterLocationBridge.tsx +30 -0
  163. package/src/hooks/useClusterLoadState.ts +73 -0
  164. package/src/hooks/useDocumentTitle.ts +25 -0
  165. package/src/hooks/useEventSource.ts +6 -0
  166. package/src/hooks/useKeyboardShortcuts.tsx +1 -0
  167. package/src/hooks/useMediaQuery.ts +21 -0
  168. package/src/hooks/useNavRailPinned.ts +46 -0
  169. package/src/hooks/useRecentResources.ts +49 -0
  170. package/src/index.css +162 -1
  171. package/src/index.ts +73 -1
  172. package/src/main.tsx +7 -5
  173. package/src/types/clusterLoadState.ts +33 -0
  174. package/src/types.ts +2 -0
  175. package/src/utils/auditBadges.ts +53 -0
  176. package/src/utils/navigation.ts +64 -1
  177. package/src/components/ui/NamespaceSelector.tsx +0 -436
@@ -1,12 +1,26 @@
1
- import { useState, useCallback } from 'react'
2
- import { TimelineList as TimelineListUI, type ActivityTypeFilter } from '@skyhook-io/k8s-ui'
3
- import type { TimeRange } from '@skyhook-io/k8s-ui'
4
- import { useChanges } from '../../api/client'
1
+ import { useState, useCallback, useMemo } from 'react'
2
+ import {
3
+ TimelineList as TimelineListUI,
4
+ eventsForApplication,
5
+ type ActivityTypeFilter,
6
+ type ActivityFilterKey,
7
+ type AppMembershipIndex,
8
+ type TimeRange,
9
+ type Topology,
10
+ } from '@skyhook-io/k8s-ui'
11
+ import { useTimelineSource } from '../../context/TimelineSource'
5
12
  import { useHasLimitedAccess } from '../../contexts/CapabilitiesContext'
6
13
  import type { NavigateToResource } from '../../utils/navigation'
7
14
  import { AlertTriangle, RefreshCw } from 'lucide-react'
8
15
 
9
- export type { ActivityTypeFilter }
16
+ export type { ActivityTypeFilter, ActivityFilterKey }
17
+
18
+ // Server-side cap on the list fetch. Generous so a busy query window isn't
19
+ // silently truncated — the list is already bounded to the selection range, so
20
+ // this only caps pathological bursts. Surfaced to the list as `truncatedAt` so a
21
+ // window that does hit it shows an end-of-list note instead of dropping silently.
22
+ const LIST_FETCH_LIMIT = 2000
23
+ const APP_SCOPED_FETCH_LIMIT = 10000
10
24
 
11
25
  interface TimelineListProps {
12
26
  namespaces: string[]
@@ -15,25 +29,69 @@ interface TimelineListProps {
15
29
  onResourceClick?: NavigateToResource
16
30
  initialFilter?: ActivityTypeFilter
17
31
  initialTimeRange?: TimeRange
32
+ showDeleted: boolean
33
+ onShowDeletedChange: (showDeleted: boolean) => void
34
+ // Shared filter state lifted to TimelineView so it survives the view switch.
35
+ search: string
36
+ onSearchChange: (value: string) => void
37
+ activityFilter: ActivityFilterKey[]
38
+ onActivityFilterChange: (keys: ActivityFilterKey[]) => void
39
+ kindFilter: string[]
40
+ onKindFilterChange: (kinds: string[]) => void
41
+ // The shared scrubber selection [from,to]. When set (retained mode always;
42
+ // local mode once the scrubber owns the range), it drives the fetch window and
43
+ // hides the built-in range dropdown so the list can't drift from the
44
+ // swimlane/URL. Retained scopes server-side; local loads the ring and bounds it
45
+ // client-side (see useLocalEvents).
46
+ selectionWindow?: { fromMs: number; toMs: number }
47
+ // LIVE mode: quantize the base fetch so the sliding window doesn't churn the
48
+ // query key every tick.
49
+ sliding?: boolean
50
+ // Time span of the rows visible in the list's scrollport — the host renders
51
+ // it as the scrubber lens so scrolling the list moves the lens.
52
+ onVisibleWindowChange?: (window: { fromMs: number; toMs: number } | null) => void
53
+ // Carries the swimlane's view window into the list on view switch (scroll target).
54
+ scrollToMs?: number
55
+ focusedAppIndex?: AppMembershipIndex
56
+ appScoped?: boolean
57
+ topology?: Topology
58
+ appScopeLoading?: boolean
18
59
  }
19
60
 
20
- export function TimelineList({ namespaces, onViewChange, currentView, onResourceClick, initialFilter, initialTimeRange }: TimelineListProps) {
61
+ export function TimelineList({ namespaces, onViewChange, currentView, onResourceClick, initialFilter, initialTimeRange, showDeleted, onShowDeletedChange, search, onSearchChange, activityFilter, onActivityFilterChange, kindFilter, onKindFilterChange, selectionWindow, sliding, onVisibleWindowChange, scrollToMs, focusedAppIndex, appScoped = false, topology, appScopeLoading = false }: TimelineListProps) {
21
62
  const hasLimitedAccess = useHasLimitedAccess()
22
- const [queryParams, setQueryParams] = useState<{ timeRange: TimeRange; kind?: string }>({
63
+ const timelineSource = useTimelineSource()
64
+ const [queryParams, setQueryParams] = useState<{ timeRange: TimeRange; kinds: string[] }>({
23
65
  timeRange: initialTimeRange ?? '1h',
66
+ kinds: [],
24
67
  })
25
68
 
26
- const handleQueryChange = useCallback((params: { timeRange: TimeRange; kind?: string }) => {
69
+ const handleQueryChange = useCallback((params: { timeRange: TimeRange; kinds: string[] }) => {
27
70
  setQueryParams(params)
28
71
  }, [])
29
72
 
30
- const { data: events = [], isLoading, isError, refetch } = useChanges({
73
+ const fetchLimit = appScoped ? APP_SCOPED_FETCH_LIMIT : LIST_FETCH_LIMIT
74
+ const { data: unscopedEvents = [], isLoading, isError, refetch } = timelineSource.useEvents({
31
75
  namespaces,
32
- kind: queryParams.kind,
76
+ kinds: queryParams.kinds,
33
77
  timeRange: queryParams.timeRange,
34
78
  includeK8sEvents: true,
35
- limit: 500,
79
+ includeManaged: appScoped,
80
+ includeDeleted: showDeleted,
81
+ limit: fetchLimit,
82
+ fromMs: selectionWindow?.fromMs,
83
+ toMs: selectionWindow?.toMs,
84
+ sliding,
36
85
  })
86
+ const events = useMemo(
87
+ () => appScoped
88
+ ? focusedAppIndex
89
+ ? eventsForApplication(unscopedEvents, topology, focusedAppIndex)
90
+ : []
91
+ : unscopedEvents,
92
+ [appScoped, focusedAppIndex, topology, unscopedEvents],
93
+ )
94
+ const sourceTruncated = unscopedEvents.length >= fetchLimit
37
95
 
38
96
  if (isError) {
39
97
  return (
@@ -54,8 +112,7 @@ export function TimelineList({ namespaces, onViewChange, currentView, onResource
54
112
  return (
55
113
  <TimelineListUI
56
114
  events={events}
57
- isLoading={isLoading}
58
- onRefresh={refetch}
115
+ isLoading={isLoading || appScopeLoading}
59
116
  onQueryChange={handleQueryChange}
60
117
  hasLimitedAccess={hasLimitedAccess}
61
118
  namespaces={namespaces}
@@ -64,6 +121,22 @@ export function TimelineList({ namespaces, onViewChange, currentView, onResource
64
121
  onResourceClick={onResourceClick}
65
122
  initialFilter={initialFilter}
66
123
  initialTimeRange={initialTimeRange}
124
+ hideRangeSelector={!!selectionWindow}
125
+ showDeleted={showDeleted}
126
+ onShowDeletedChange={onShowDeletedChange}
127
+ search={search}
128
+ onSearchChange={onSearchChange}
129
+ activityFilter={activityFilter}
130
+ onActivityFilterChange={onActivityFilterChange}
131
+ kindFilter={kindFilter}
132
+ onKindFilterChange={onKindFilterChange}
133
+ onVisibleWindowChange={onVisibleWindowChange}
134
+ scrollToMs={scrollToMs}
135
+ truncatedAt={fetchLimit}
136
+ isTruncated={sourceTruncated}
137
+ truncationMessage={appScoped && sourceTruncated
138
+ ? `Showing application activity found in the newest ${fetchLimit.toLocaleString()} events in this range — narrow the query to see older activity`
139
+ : undefined}
67
140
  />
68
141
  )
69
142
  }