Skip to content

Commit

Permalink
Ensure lists update when switching between workspaces with the same n…
Browse files Browse the repository at this point in the history
…umber of rows (#12449)
  • Loading branch information
richard-cox authored Nov 1, 2024
1 parent cf25646 commit 3387613
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 5 deletions.
27 changes: 26 additions & 1 deletion shell/components/ResourceTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,31 @@ export default {
// Confirm which store we're in, if schema isn't available we're probably showing a list with different types
const inStore = this.schema?.id ? this.$store.getters['currentStore'](this.schema.id) : undefined;
return { inStore };
return {
inStore,
/**
* Override the sortGenerationFn given changes in the rows we pass through to sortable table
*
* Primary purpose is to directly connect an iteration of `rows` with a sortGeneration string. This avoids
* reactivity issues where `rows` hasn't yet changed but something like workspaces has (stale values stored against fresh key)
*/
sortGeneration: undefined
};
},
watch: {
filteredRows: {
handler() {
// This is only prevalent in fleet world and the workspace switcher
// - it's singular (a --> b --> c) instead of namespace switchers additive (a --> a+b --> a)
// - this means it's much more likely to switch between resource sets containing the same mount of rows
//
if (this.currentProduct.showWorkspaceSwitcher) {
this.sortGeneration = this.safeSortGenerationFn(this.schema, this.$store);
}
},
immediate: true
}
},
computed: {
Expand Down Expand Up @@ -556,6 +580,7 @@ export default {
:adv-filter-hide-labels-as-cols="advFilterHideLabelsAsCols"
:adv-filter-prevent-filtering-labels="advFilterPreventFilteringLabels"
:key-field="keyField"
:sortGeneration="sortGeneration"
:sort-generation-fn="safeSortGenerationFn"
:use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
:force-update-live-and-delayed="forceUpdateLiveAndDelayed"
Expand Down
18 changes: 17 additions & 1 deletion shell/components/SortableTable/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import ButtonMultiAction from '@shell/components/ButtonMultiAction.vue';
// --> filtering.js filteredRows
// --> paging.js pageRows
// --> grouping.js groupedRows
// --> index.vue displayedRows
// --> index.vue displayRows
export default {
name: 'SortableTable',
Expand Down Expand Up @@ -77,11 +77,13 @@ export default {
type: Array,
required: true
},
rows: {
// The array of objects to show
type: Array,
required: true
},
keyField: {
// Field that is unique for each row.
type: String,
Expand Down Expand Up @@ -285,11 +287,25 @@ export default {
default: true
},
/**
* Provide a unique key that will provide a new value given changes to the environment that
* should kick off an update to table rows (for instance resource list generation or change of namespace)
*
* This does not have to update given internal facets like sort order or direction
*/
sortGenerationFn: {
type: Function,
default: null,
},
/**
* Can be used in place of sortGenerationFn
*/
sortGeneration: {
type: String,
default: null
},
/**
* The list will always be sorted by these regardless of what the user has selected
*/
Expand Down
14 changes: 11 additions & 3 deletions shell/components/SortableTable/sorting.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,17 @@ export default {

let key;

if ( this.sortGenerationFn ) {
key = `${ this.sortGenerationFn.apply(this) }/${ this.rows.length }/${ this.descending }/${ this.sortFields.join(',') }`;

// Why is sortGeneration needed when we have sortGenerationFn?
// 1. sortGenerationFn is called when this fn is kicked off and returns latest and greatest string (given things like namespace)
// 2. it can be kicked off with stale rows... which is then stored against latest string
// 3. when updates rows comes through... sortGenerationFn returns same string
// 4. we therefor think nothing has changed and return old, stale rows
// This is avoided by outside storage of sortGeneration against rows
// (it would be nice to have that hash on the rows object itself, but it gets messy)
const sortGenerationKey = this.sortGeneration || this.sortGenerationFn?.apply(this);

if ( sortGenerationKey) {
key = `${ sortGenerationKey }/${ this.rows.length }/${ this.descending }/${ this.sortFields.join(',') }`;
if ( this.cacheKey === key ) {
return this.cachedRows;
}
Expand Down

0 comments on commit 3387613

Please sign in to comment.