@skyhook-io/k8s-ui 1.8.1 → 1.8.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyhook-io/k8s-ui",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/skyhook-io/radar",
@@ -1,4 +1,4 @@
1
- import { provenanceSource, HEALTH_META, type AppWorkload } from '../../utils/applications'
1
+ import { provenanceSource, HEALTH_META, appSourceLabel, isDeclaredAppSource, APP_IDENTITY_ANNOTATION, type AppWorkload } from '../../utils/applications'
2
2
  import { midTruncate } from '../../utils/format'
3
3
 
4
4
  // Structured tooltip content for the application chips. Both render a short
@@ -105,26 +105,53 @@ export function CategoryTooltip({
105
105
  )
106
106
  }
107
107
 
108
- // AppIdentityTooltip — why these instances are grouped. One line per distinct
109
- // evidence in the ProvenanceTooltip idiom (signals as inline-code, long repo
110
- // refs mid-truncated), plus a small flag when the grouping is heuristic-only.
111
- // No member list the env pills next to this chip already show the instances.
108
+ // AppIdentityTooltip — why these instances are grouped, and (in the fleet view)
109
+ // whether the grouping folds across clusters + how to make it. A clear
110
+ // source-driven headline, the per-evidence detail lines, and when `fleet` and
111
+ // the identity isn't a declared cross-cluster origin the canonical "how to
112
+ // fold" answer, so the question and its answer share one surface.
113
+ //
114
+ // `source`/`portable` come from the row's identity; absent (an older host that
115
+ // doesn't pass them) the headline degrades to the evidence lines. `fleet` gates
116
+ // the cross-cluster "how to fold" line — single-cluster (OSS) has no clusters to
117
+ // fold across, so it shows only the grouping evidence.
112
118
  export function AppIdentityTooltip({
113
119
  members,
120
+ source,
121
+ portable,
122
+ fleet,
114
123
  }: {
115
124
  identityKey?: string
116
125
  members: { name: string; env: string; confidence: string; evidence: string }[]
126
+ source?: string
127
+ portable?: boolean
128
+ fleet?: boolean
117
129
  }) {
118
130
  const evidences = Array.from(new Set(members.map((m) => m.evidence).filter(Boolean)))
119
131
  const heuristicOnly = members.every((m) => m.confidence !== 'high')
132
+ // The wire `portable` flag is authoritative; fall back to deriving it from the
133
+ // source when an older host doesn't pass it.
134
+ const folds = portable ?? isDeclaredAppSource(source)
120
135
  return (
121
- <div className="max-w-xs space-y-1">
136
+ <div className="max-w-xs space-y-1.5">
137
+ {source && <div className="text-xs font-medium text-theme-text-primary">Grouped by {appSourceLabel(source)}.</div>}
122
138
  {evidences.map((e, i) => (
123
- <div key={i} className="text-xs text-theme-text-primary">
139
+ <div key={i} className="text-xs text-theme-text-secondary">
124
140
  <EvidenceLine evidence={e} />
125
141
  </div>
126
142
  ))}
127
- {heuristicOnly && (
143
+ {fleet && folds && (
144
+ <div className="text-[10px] uppercase tracking-wide text-theme-text-tertiary">folds across clusters</div>
145
+ )}
146
+ {fleet && source !== undefined && !folds && (
147
+ <div className="space-y-1 border-t border-theme-border pt-1.5">
148
+ <div className="text-[11px] leading-snug text-theme-text-secondary">
149
+ Shown per-cluster — a name can't prove two clusters run the same app. To fold it across clusters, set the same{' '}
150
+ <code className="inline-code">{APP_IDENTITY_ANNOTATION}</code> on its workloads in each cluster, or deploy it via Argo CD / Flux with the environment in the source path.
151
+ </div>
152
+ </div>
153
+ )}
154
+ {!fleet && heuristicOnly && !source && (
128
155
  <div className={`text-[10px] uppercase tracking-wide ${HEALTH_META.degraded.text}`}>heuristic · medium confidence</div>
129
156
  )}
130
157
  </div>