Skip to content

Commit 3bc8a3a

Browse files
committed
Address Bugbot: custom column sort/filter/migration edge cases
- Make custom (and any extra) columns header-sortable when they carry getSortValue — previously the header gated sortability on a hardcoded built-in key list, so custom columns couldn't be sorted despite the wiring. - Add extraColumnsByKey to the filteredResources deps: custom columns hydrate in a later effect, so a reload with a URL filter on a custom key could keep a cached result computed before those columns existed. - removeCustomColumn now also clears any columnFilters entry and resets sort for that key — otherwise the table keeps filtering (and syncing to the URL) on a column that no longer exists, with no UI to clear it. - Don't run the stale-pure-defaults migration when custom columns are persisted — it cleared them from storage (and un-hid hidden ones).
1 parent 597bbb5 commit 3bc8a3a

1 file changed

Lines changed: 21 additions & 3 deletions

File tree

packages/k8s-ui/src/components/resources/ResourcesView.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,9 +2203,12 @@ export function ResourcesView({
22032203
const extraKeys = extras.map(c => c.key)
22042204
if (saved) {
22052205
// If saved columns are just the defaults but this kind has specialized columns,
2206-
// discard the stale save and use the specialized columns instead
2206+
// discard the stale save and use the specialized columns instead. User-added
2207+
// custom columns mean the blob isn't a stale pure-defaults save — keep it, or
2208+
// the migration would clear them from storage (and un-hide hidden ones).
22072209
const defaultKeys = DEFAULT_COLUMNS.map(c => c.key)
22082210
const isStaleDefaults = kindColumns !== DEFAULT_COLUMNS &&
2211+
!savedCustom.length &&
22092212
saved.visible.length === defaultKeys.length &&
22102213
saved.visible.every(v => defaultKeys.includes(v))
22112214
if (isStaleDefaults) {
@@ -2369,7 +2372,20 @@ export function ResourcesView({
23692372
next.delete(key)
23702373
return next
23712374
})
2372-
}, [])
2375+
// Drop any filter/sort that targeted the removed column — otherwise the
2376+
// table keeps filtering (and syncing to the URL) on a key with no column
2377+
// and no UI to clear it, and sort silently references a gone column.
2378+
setColumnFilters(prev => {
2379+
if (!(key in prev)) return prev
2380+
const next = { ...prev }
2381+
delete next[key]
2382+
return next
2383+
})
2384+
if (sortColumn === key) {
2385+
setSortColumn(null)
2386+
setSortDirection(null)
2387+
}
2388+
}, [sortColumn])
23732389

23742390
// Keyboard shortcut: / to focus search
23752391
useRegisterShortcut({
@@ -3458,7 +3474,7 @@ export function ResourcesView({
34583474
}
34593475

34603476
return result
3461-
}, [resources, searchTerm, regexMode, searchRegex, columnFilters, problemFilters, showInactiveReplicaSets, labelSelector, ownerKind, ownerName, selectedKind.name, sortColumn, sortDirection, getSortValue, podMatchesProblemFilter])
3477+
}, [resources, searchTerm, regexMode, searchRegex, columnFilters, problemFilters, showInactiveReplicaSets, labelSelector, ownerKind, ownerName, selectedKind.name, sortColumn, sortDirection, getSortValue, extraColumnsByKey, podMatchesProblemFilter])
34623478

34633479
// For nodes table: compute the majority minor version so outliers can be highlighted
34643480
const majorityNodeMinorVersion = useMemo(() => {
@@ -4383,7 +4399,9 @@ export function ResourcesView({
43834399
</th>
43844400
)}
43854401
{columns.map((col, colIdx) => {
4402+
// Built-in sortable keys, plus any extra/custom column that carries its own getSortValue.
43864403
const isSortable = ['name', 'namespace', 'age', 'status', 'ready', 'restarts', 'type', 'version', 'desired', 'available', 'upToDate', 'lastSeen', 'count', 'reason', 'object', 'cpu', 'memory', 'containers'].includes(col.key)
4404+
|| !!extraColumnsByKey.get(col.key)?.getSortValue
43874405
const isSorted = sortColumn === col.key
43884406
const isLastCol = colIdx === columns.length - 1
43894407
const filterCol = filterableColumnMap.get(col.key)

0 commit comments

Comments
 (0)