@skyhook-io/k8s-ui 1.13.3 → 1.13.4
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.
- package/package.json +1 -1
- package/src/components/applications/AppTooltips.tsx +13 -1
- package/src/components/applications/ApplicationDetail.test.tsx +25 -0
- package/src/components/applications/ApplicationDetail.tsx +39 -7
- package/src/components/applications/ApplicationsView.tsx +18 -3
- package/src/components/applications/ReadyBar.tsx +3 -2
- package/src/components/applications/applications-view.test.tsx +91 -0
- package/src/components/cluster-switcher/ClusterSwitcher.tsx +4 -1
- package/src/components/issues/IssuesView.tsx +40 -31
- package/src/components/issues/ResourceIssuesSection.tsx +3 -2
- package/src/components/issues/index.ts +3 -1
- package/src/components/issues/issue-timing.ts +123 -4
- package/src/components/issues/issues.test.ts +221 -10
- package/src/components/issues/types.ts +31 -5
- package/src/components/namespace-switcher/NamespacePicker.tsx +21 -13
- package/src/components/resources/ResourcesView.tsx +964 -96
- package/src/components/resources/column-settings-key.test.ts +98 -0
- package/src/components/resources/column-visibility-merge.test.ts +64 -0
- package/src/components/resources/curated-column-ownership.test.ts +236 -0
- package/src/components/resources/gateway-policy-status.test.ts +291 -0
- package/src/components/resources/gateway-policy-status.ts +237 -0
- package/src/components/resources/generic-status.test.ts +199 -0
- package/src/components/resources/generic-status.ts +171 -0
- package/src/components/resources/gpu-ecosystem-registry.test.ts +63 -0
- package/src/components/resources/index.ts +9 -1
- package/src/components/resources/istio-gateway-filter.test.ts +97 -0
- package/src/components/resources/printer-columns.test.ts +298 -0
- package/src/components/resources/printer-columns.ts +249 -0
- package/src/components/resources/renderers/EventRenderer.test.tsx +50 -1
- package/src/components/resources/renderers/EventRenderer.tsx +3 -5
- package/src/components/resources/renderers/GenericRenderer.tsx +18 -83
- package/src/components/resources/renderers/HPARenderer.test.tsx +28 -0
- package/src/components/resources/renderers/HPARenderer.tsx +6 -1
- package/src/components/resources/renderers/MetricsUnavailableNotice.tsx +2 -1
- package/src/components/resources/renderers/PVCRenderer.test.tsx +44 -0
- package/src/components/resources/renderers/PVCRenderer.tsx +19 -2
- package/src/components/resources/renderers/RolloutRenderer.test.tsx +35 -0
- package/src/components/resources/renderers/RolloutRenderer.tsx +22 -3
- package/src/components/resources/renderers/WorkloadRenderer.test.tsx +83 -0
- package/src/components/resources/renderers/WorkloadRenderer.tsx +25 -65
- package/src/components/resources/renderers/amd-gpu-cells.tsx +36 -0
- package/src/components/resources/renderers/inference-gateway-cells.tsx +62 -0
- package/src/components/resources/renderers/jobset-lws-cells.tsx +82 -0
- package/src/components/resources/renderers/kai-cells.tsx +67 -0
- package/src/components/resources/renderers/kaito-cells.tsx +62 -0
- package/src/components/resources/renderers/kserve-cells.tsx +145 -0
- package/src/components/resources/renderers/kubeflow-training-cells.tsx +72 -0
- package/src/components/resources/renderers/kueue-cells.tsx +176 -0
- package/src/components/resources/renderers/nim-cells.tsx +81 -0
- package/src/components/resources/renderers/ray-cells.tsx +124 -0
- package/src/components/resources/renderers/volcano-cells.tsx +140 -0
- package/src/components/resources/resource-utils-amd-gpu.ts +61 -0
- package/src/components/resources/resource-utils-gpu-ecosystem.test.ts +222 -0
- package/src/components/resources/resource-utils-hpa.test.ts +4 -0
- package/src/components/resources/resource-utils-hpa.ts +6 -2
- package/src/components/resources/resource-utils-inference-gateway.ts +119 -0
- package/src/components/resources/resource-utils-jobset-lws.ts +117 -0
- package/src/components/resources/resource-utils-kai.ts +105 -0
- package/src/components/resources/resource-utils-kaito.ts +114 -0
- package/src/components/resources/resource-utils-kserve.ts +186 -0
- package/src/components/resources/resource-utils-kubeflow-training.ts +121 -0
- package/src/components/resources/resource-utils-kueue.ts +198 -0
- package/src/components/resources/resource-utils-nim.ts +109 -0
- package/src/components/resources/resource-utils-ray.ts +214 -0
- package/src/components/resources/resource-utils-rollout.test.ts +183 -0
- package/src/components/resources/resource-utils-velero.test.ts +30 -0
- package/src/components/resources/resource-utils-volcano.ts +176 -0
- package/src/components/resources/resource-utils.ts +156 -47
- package/src/components/resources/resources-column-filter.test.ts +27 -1
- package/src/components/resources/workload-rollout-golden.test.ts +55 -0
- package/src/components/shared/CreateResourceDialog.tsx +1 -0
- package/src/components/shared/EditableYamlView.tsx +4 -2
- package/src/components/shared/ResourceActionsBar.tsx +170 -25
- package/src/components/shared/ResourceRendererDispatch.test.tsx +206 -1
- package/src/components/shared/ResourceRendererDispatch.tsx +84 -40
- package/src/components/shared/SetImageDialog.test.ts +129 -0
- package/src/components/shared/SetImageDialog.tsx +577 -0
- package/src/components/shared/index.ts +1 -0
- package/src/components/shared/revision-role-badges.test.ts +56 -4
- package/src/components/timeline/TimelineList.tsx +19 -3
- package/src/components/timeline/TimelineSwimlanes.tsx +11 -3
- package/src/components/trace/ReachabilityView.tsx +1 -1
- package/src/components/ui/drawer-components.tsx +12 -0
- package/src/components/workload/WorkloadRolloutNotice.tsx +60 -0
- package/src/components/workload/WorkloadView.tsx +144 -81
- package/src/hooks/useProgressiveRefresh.ts +37 -0
- package/src/source-hygiene.test.ts +28 -0
- package/src/theme/tailwind-theme.css +4 -0
- package/src/types/core.ts +55 -0
- package/src/utils/api-resources.test.ts +40 -1
- package/src/utils/api-resources.ts +11 -1
- package/src/utils/applications.ts +50 -0
- package/src/utils/bulk-workload-actions.test.ts +20 -0
- package/src/utils/bulk-workload-actions.ts +15 -0
- package/src/utils/navigation.test.ts +31 -1
- package/src/utils/navigation.ts +21 -2
- package/src/utils/workload-rollout.ts +292 -0
|
@@ -30,7 +30,7 @@ import { isChangeEvent, isHistoricalEvent } from '../../types'
|
|
|
30
30
|
import { getHealthBadgeColor, SEVERITY_BADGE } from '../../utils/badge-colors'
|
|
31
31
|
import { ResourceRefBadge } from '../ui/drawer-components'
|
|
32
32
|
import type { NavigateToResource } from '../../utils/navigation'
|
|
33
|
-
import {
|
|
33
|
+
import { kindToPluralWithGroup, refToSelectedResource, apiVersionToGroup } from '../../utils/navigation'
|
|
34
34
|
import { pluralize } from '../../utils/pluralize'
|
|
35
35
|
|
|
36
36
|
/** Format resource age (e.g., "3d", "5h", "10m") */
|
|
@@ -604,7 +604,15 @@ function ActivityCard({ item, expanded, onToggle, onResourceClick, compact, sele
|
|
|
604
604
|
<button
|
|
605
605
|
onClick={(e) => {
|
|
606
606
|
e.stopPropagation()
|
|
607
|
-
onResourceClick?.({
|
|
607
|
+
onResourceClick?.({
|
|
608
|
+
kind: kindToPluralWithGroup(
|
|
609
|
+
item.kind,
|
|
610
|
+
apiVersionToGroup(item.apiVersion),
|
|
611
|
+
),
|
|
612
|
+
namespace: item.namespace,
|
|
613
|
+
name: item.name,
|
|
614
|
+
group: apiVersionToGroup(item.apiVersion),
|
|
615
|
+
})
|
|
608
616
|
}}
|
|
609
617
|
className="flex items-center gap-2 hover:bg-theme-elevated/50 rounded px-1 -ml-1 transition-colors group"
|
|
610
618
|
>
|
|
@@ -777,7 +785,15 @@ function AggregatedActivityCard({ first, last, count, reason, expanded, onToggle
|
|
|
777
785
|
<button
|
|
778
786
|
onClick={(e) => {
|
|
779
787
|
e.stopPropagation()
|
|
780
|
-
onResourceClick?.({
|
|
788
|
+
onResourceClick?.({
|
|
789
|
+
kind: kindToPluralWithGroup(
|
|
790
|
+
first.kind,
|
|
791
|
+
apiVersionToGroup(first.apiVersion),
|
|
792
|
+
),
|
|
793
|
+
namespace: first.namespace,
|
|
794
|
+
name: first.name,
|
|
795
|
+
group: apiVersionToGroup(first.apiVersion),
|
|
796
|
+
})
|
|
781
797
|
}}
|
|
782
798
|
className="flex items-center gap-2 hover:bg-theme-elevated/50 rounded px-1 -ml-1 transition-colors group"
|
|
783
799
|
>
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from 'lucide-react'
|
|
27
27
|
import type { TimelineEvent, Topology } from '../../types'
|
|
28
28
|
import type { NavigateToResource } from '../../utils/navigation'
|
|
29
|
-
import {
|
|
29
|
+
import { kindToPluralWithGroup, apiVersionToGroup } from '../../utils/navigation'
|
|
30
30
|
import { PaneLoader } from '../ui/PaneLoader'
|
|
31
31
|
import { TimelineToolbar } from './TimelineToolbar'
|
|
32
32
|
import { sortTimelineLanes, TIMELINE_SORT_DEFAULT, type TimelineSort } from './timeline-lane-sort'
|
|
@@ -770,7 +770,7 @@ export function TimelineSwimlanes({ events, isLoading, onResourceClick, viewMode
|
|
|
770
770
|
onNavigatePath(gitOpsPath)
|
|
771
771
|
return
|
|
772
772
|
}
|
|
773
|
-
onResourceClick?.({ kind:
|
|
773
|
+
onResourceClick?.({ kind: kindToPluralWithGroup(kind, group ?? ''), namespace, name, group })
|
|
774
774
|
}, [onNavigatePath, onResourceClick])
|
|
775
775
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
776
776
|
const [zoom, setZoom] = useState(1)
|
|
@@ -3097,7 +3097,15 @@ export function EventDetailPanel({ events, selectedId, onSelectId, onClose, onRe
|
|
|
3097
3097
|
// divider separates "the dot you clicked" from "what happened around it".
|
|
3098
3098
|
const neighborsFrom = events.length === 1 && railEvents.length > 1 ? 1 : -1
|
|
3099
3099
|
const openResource = () =>
|
|
3100
|
-
onResourceClick?.({
|
|
3100
|
+
onResourceClick?.({
|
|
3101
|
+
kind: kindToPluralWithGroup(
|
|
3102
|
+
selected.kind,
|
|
3103
|
+
apiVersionToGroup(selected.apiVersion),
|
|
3104
|
+
),
|
|
3105
|
+
namespace: selected.namespace,
|
|
3106
|
+
name: selected.name,
|
|
3107
|
+
group: apiVersionToGroup(selected.apiVersion),
|
|
3108
|
+
})
|
|
3101
3109
|
|
|
3102
3110
|
return (
|
|
3103
3111
|
<div
|
|
@@ -535,7 +535,7 @@ export function problemRows(
|
|
|
535
535
|
// entry can carry several findings, and one origin several failed routes.
|
|
536
536
|
// `k` is what `seen` just proved unique, so pairing them is what makes the
|
|
537
537
|
// React key safe rather than each caller having to get it right.
|
|
538
|
-
rows.push({ ...r, key: `${r.key}
|
|
538
|
+
rows.push({ ...r, key: `${r.key}\x00${k}` })
|
|
539
539
|
}
|
|
540
540
|
const refNode = (r?: ResourceRef) => (r ? `n:${r.kind}/${r.namespace ?? ''}/${r.name || 'pods'}` : '')
|
|
541
541
|
|
|
@@ -733,6 +733,18 @@ export function formatKindName(kind: string): string {
|
|
|
733
733
|
resourceclaims: 'ResourceClaim', resourceclaimtemplates: 'ResourceClaimTemplate',
|
|
734
734
|
deviceclasses: 'DeviceClass', resourceslices: 'ResourceSlice',
|
|
735
735
|
clusterpolicies: 'ClusterPolicy', nvidiadrivers: 'NVIDIADriver',
|
|
736
|
+
clusterqueues: 'ClusterQueue', localqueues: 'LocalQueue', resourceflavors: 'ResourceFlavor',
|
|
737
|
+
admissionchecks: 'AdmissionCheck', provisioningrequests: 'ProvisioningRequest',
|
|
738
|
+
rayclusters: 'RayCluster', rayjobs: 'RayJob', rayservices: 'RayService', raycronjobs: 'RayCronJob',
|
|
739
|
+
leaderworkersets: 'LeaderWorkerSet', jobsets: 'JobSet',
|
|
740
|
+
inferenceservices: 'InferenceService', servingruntimes: 'ServingRuntime',
|
|
741
|
+
clusterservingruntimes: 'ClusterServingRuntime', inferencegraphs: 'InferenceGraph',
|
|
742
|
+
trainedmodels: 'TrainedModel', llminferenceservices: 'LLMInferenceService',
|
|
743
|
+
inferencepools: 'InferencePool', inferenceobjectives: 'InferenceObjective',
|
|
744
|
+
jobflows: 'JobFlow', jobtemplates: 'JobTemplate', ragengines: 'RAGEngine',
|
|
745
|
+
nimservices: 'NIMService', nimcaches: 'NIMCache', nimpipelines: 'NIMPipeline',
|
|
746
|
+
deviceconfigs: 'DeviceConfig',
|
|
747
|
+
pytorchjobs: 'PyTorchJob', tfjobs: 'TFJob', mpijobs: 'MPIJob', trainjobs: 'TrainJob',
|
|
736
748
|
}
|
|
737
749
|
if (names[k]) return names[k]
|
|
738
750
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { AlertTriangle, Check, Clock3, Loader2, Pause } from 'lucide-react'
|
|
2
|
+
import { Badge, type BadgeSeverity } from '../ui/Badge'
|
|
3
|
+
import type { WorkloadRolloutActivity } from '../../utils/workload-rollout'
|
|
4
|
+
|
|
5
|
+
export function WorkloadRolloutNotice({
|
|
6
|
+
activity,
|
|
7
|
+
recentImageSave = false,
|
|
8
|
+
className = '',
|
|
9
|
+
}: {
|
|
10
|
+
activity: WorkloadRolloutActivity
|
|
11
|
+
recentImageSave?: boolean
|
|
12
|
+
className?: string
|
|
13
|
+
}) {
|
|
14
|
+
if (activity.phase === 'idle' && !recentImageSave) return null
|
|
15
|
+
const shown = activity.phase === 'idle' && recentImageSave
|
|
16
|
+
? { ...activity, phase: 'applying' as const, active: true, label: 'Waiting for controller', detail: 'The template change was accepted; waiting for live rollout status' }
|
|
17
|
+
: activity
|
|
18
|
+
const severity: BadgeSeverity = shown.phase === 'stalled'
|
|
19
|
+
? 'error'
|
|
20
|
+
: shown.phase === 'paused' || shown.manual
|
|
21
|
+
? 'warning'
|
|
22
|
+
: 'info'
|
|
23
|
+
const Icon = shown.phase === 'stalled'
|
|
24
|
+
? AlertTriangle
|
|
25
|
+
: shown.phase === 'paused'
|
|
26
|
+
? Pause
|
|
27
|
+
: shown.phase === 'waiting'
|
|
28
|
+
? Clock3
|
|
29
|
+
: Loader2
|
|
30
|
+
const warning = shown.phase === 'paused' || shown.manual
|
|
31
|
+
const containerTone = shown.phase === 'stalled'
|
|
32
|
+
? 'border-semantic-error/30 bg-semantic-error/5'
|
|
33
|
+
: warning
|
|
34
|
+
? 'border-semantic-warning/30 bg-semantic-warning/5'
|
|
35
|
+
: 'border-theme-border bg-accent-muted'
|
|
36
|
+
const iconTone = shown.phase === 'stalled'
|
|
37
|
+
? 'text-semantic-error'
|
|
38
|
+
: warning
|
|
39
|
+
? 'text-semantic-warning'
|
|
40
|
+
: 'text-accent-text'
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className={`rounded-lg border px-3 py-2.5 shadow-theme-sm ${containerTone} ${className}`} role={shown.phase === 'stalled' ? 'alert' : 'status'}>
|
|
44
|
+
<div className="flex min-w-0 items-start gap-2.5">
|
|
45
|
+
<Icon className={`mt-0.5 h-4 w-4 shrink-0 ${iconTone} ${shown.active && (shown.phase === 'applying' || shown.phase === 'progressing') ? 'animate-spin' : ''}`} />
|
|
46
|
+
<div className="min-w-0 flex-1">
|
|
47
|
+
<div className="flex min-w-0 flex-wrap items-center gap-1.5">
|
|
48
|
+
{recentImageSave && (
|
|
49
|
+
<span className="inline-flex items-center gap-1 text-xs font-medium text-theme-text-secondary">
|
|
50
|
+
<Check className="h-3.5 w-3.5" /> Image saved <span aria-hidden>·</span>
|
|
51
|
+
</span>
|
|
52
|
+
)}
|
|
53
|
+
<Badge severity={severity}>{shown.label}</Badge>
|
|
54
|
+
</div>
|
|
55
|
+
{shown.detail && <div className="mt-1 text-xs leading-5 text-theme-text-secondary">{shown.detail}</div>}
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
)
|
|
60
|
+
}
|