diff --git a/shell/assets/translations/en-us.yaml b/shell/assets/translations/en-us.yaml index a8863c5237..7a3e9a27fc 100644 --- a/shell/assets/translations/en-us.yaml +++ b/shell/assets/translations/en-us.yaml @@ -6174,7 +6174,7 @@ performance: label: Incremental Loading setting: You can configure the threshold above which incremental loading will be used. description: |- - When enabled, resources will appear more quickly, but it may take slightly longer to load the entire set of resources. This setting only applies to the following resources: Pods, Deployments, Cron Jobs, Daemon Sets, Jobs, Stateful Sets, Replica Sets, Replication Controllers, Workloads and Secrets. + When enabled, resources will appear more quickly, but it may take slightly longer to load the entire set of resources. This setting only applies to resources that come from the Kubernetes API checkboxLabel: Enable incremental loading inputLabel: Resource Threshold manualRefresh: @@ -6183,7 +6183,7 @@ performance: setting: You can configure a threshold above which manual refresh will be enabled. buttonTooltip: Refresh list description: |- - When enabled, list data will not auto-update but instead the user must manually trigger a list-view refresh. This setting only applies to the following resources: Pods, Deployments, Cron Jobs, Daemon Sets, Jobs, Stateful Sets, Replica Sets, Replication Controllers, Workloads and Secrets. + When enabled, list data will not auto-update but instead the user must manually trigger a list-view refresh. This setting only applies to resources that come from the Kubernetes API checkboxLabel: Enable manual refresh of data for lists inputLabel: Resource Threshold websocketNotification: diff --git a/shell/components/ExplorerProjectsNamespaces.vue b/shell/components/ExplorerProjectsNamespaces.vue index b2a3537b44..8fad21f034 100644 --- a/shell/components/ExplorerProjectsNamespaces.vue +++ b/shell/components/ExplorerProjectsNamespaces.vue @@ -10,12 +10,14 @@ import { mapPref, GROUP_RESOURCES, ALL_NAMESPACES } from '@shell/store/prefs'; import MoveModal from '@shell/components/MoveModal'; import { defaultTableSortGenerationFn } from '@shell/components/ResourceTable.vue'; import { NAMESPACE_FILTER_ALL_ORPHANS } from '@shell/utils/namespace-filter'; +import ResourceFetch from '@shell/mixins/resource-fetch'; export default { name: 'ListProjectNamespace', components: { Masthead, MoveModal, ResourceTable }, + mixins: [ResourceFetch], props: { createProjectLocationOverride: { @@ -42,14 +44,15 @@ export default { return; } - this.namespaces = await this.$store.dispatch(`${ inStore }/findAll`, { type: NAMESPACE }); + await this.$fetchType(NAMESPACE); this.projects = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.PROJECT, opt: { force: true } }); }, data() { return { + loadResources: [NAMESPACE], + loadIndeterminate: true, schema: null, - namespaces: [], projects: [], projectSchema: null, MANAGEMENT, @@ -66,6 +69,17 @@ export default { computed: { ...mapGetters(['currentCluster', 'currentProduct']), + namespaces() { + const inStore = this.$store.getters['currentStore'](NAMESPACE); + + return this.$store.getters[`${ inStore }/all`](NAMESPACE); + }, + loading() { + return !this.currentCluster || this.namespaces.length ? false : this.$fetchState.pending; + }, + showIncrementalLoadingIndicator() { + return this.perfConfig?.incrementalLoading?.enabled; + }, isNamespaceCreatable() { return (this.schema?.collectionMethods || []).includes('POST'); }, @@ -309,6 +323,9 @@ export default { :favorite-resource="VIRTUAL_TYPES.PROJECT_NAMESPACES" :create-location="createProjectLocation" :create-button-label="t('projectNamespaces.createProject')" + :show-incremental-loading-indicator="showIncrementalLoadingIndicator" + :load-resources="loadResources" + :load-indeterminate="loadIndeterminate" /> [] + }, + + loadIndeterminate: { + type: Boolean, + default: false + }, + + showIncrementalLoadingIndicator: { + type: Boolean, + default: false + }, /** * Inherited global identifier prefix for tests @@ -155,7 +171,11 @@ export default {

{{ _typeDisplay }}

- +
diff --git a/shell/components/ResourceList/ResourceLoadingIndicator.vue b/shell/components/ResourceList/ResourceLoadingIndicator.vue index 30cb920d88..9e07fac3b7 100644 --- a/shell/components/ResourceList/ResourceLoadingIndicator.vue +++ b/shell/components/ResourceList/ResourceLoadingIndicator.vue @@ -16,10 +16,6 @@ export default { indeterminate: { type: Boolean, default: false, - }, - rows: { - type: Array, - default: undefined, } }, @@ -32,10 +28,6 @@ export default { computed: { // Count of rows - either from the data provided or from the rows for the first resource rowsCount() { - if (this.rows) { - return this.rows.length; - } - if (this.resources.length > 0) { const existingData = this.$store.getters[`${ this.inStore }/all`](this.resources[0]) || []; diff --git a/shell/components/ResourceList/index.vue b/shell/components/ResourceList/index.vue index 9e01d25e1e..0f71be3516 100644 --- a/shell/components/ResourceList/index.vue +++ b/shell/components/ResourceList/index.vue @@ -3,7 +3,7 @@ import ResourceTable from '@shell/components/ResourceTable'; import Loading from '@shell/components/Loading'; import Masthead from './Masthead'; import ResourceLoadingIndicator from './ResourceLoadingIndicator'; -import ResourceFetch, { TYPES_RESTRICTED } from '@shell/mixins/resource-fetch'; +import ResourceFetch from '@shell/mixins/resource-fetch'; export default { components: { @@ -43,8 +43,8 @@ export default { if (component?.$loadingResources) { const { loadResources, loadIndeterminate } = component?.$loadingResources(this.$route, this.$store); - this.loadResources = loadResources; - this.loadIndeterminate = loadIndeterminate; + this.loadResources = loadResources || [resource]; + this.loadIndeterminate = loadIndeterminate || false; } } @@ -55,11 +55,7 @@ export default { return; } - if (TYPES_RESTRICTED.includes(resource)) { - this.rows = await this.$fetchType(resource); - } else { - this.rows = await store.dispatch(`${ inStore }/findAll`, { type: resource }); - } + await this.$fetchType(resource); } }, @@ -75,13 +71,10 @@ export default { const showMasthead = getters[`type-map/optionsFor`](resource).showListMasthead; - const existingData = getters[`${ inStore }/all`](resource) || []; - return { inStore, schema, hasListComponent, - hasData: existingData.length > 0, showMasthead: showMasthead === undefined ? true : showMasthead, resource, // manual refresh @@ -89,7 +82,6 @@ export default { watch: false, force: false, // Provided by fetch later - rows: [], customTypeDisplay: null, // incremental loading loadResources: [resource], @@ -111,10 +103,6 @@ export default { return this.$store.getters['type-map/groupByFor'](this.schema); }, - loading() { - return this.hasData ? false : this.$fetchState.pending; - }, - showIncrementalLoadingIndicator() { return this.perfConfig?.incrementalLoading?.enabled; } @@ -142,18 +130,16 @@ export default { :type-display="customTypeDisplay" :schema="schema" :resource="resource" + :show-incremental-loading-indicator="showIncrementalLoadingIndicator" + :load-resources="loadResources" + :load-indeterminate="loadIndeterminate" > -
diff --git a/shell/components/SortableTable/index.vue b/shell/components/SortableTable/index.vue index 3243c26a24..04f19d9285 100644 --- a/shell/components/SortableTable/index.vue +++ b/shell/components/SortableTable/index.vue @@ -368,16 +368,19 @@ export default { immediate: true }, - isManualRefreshLoading(neu, old) { - this.currentPhase = neu ? ASYNC_BUTTON_STATES.WAITING : ASYNC_BUTTON_STATES.ACTION; + isManualRefreshLoading: { + handler(neu, old) { + this.currentPhase = neu ? ASYNC_BUTTON_STATES.WAITING : ASYNC_BUTTON_STATES.ACTION; - // setTimeout is needed so that this is pushed further back on the JS computing queue - // because nextTick isn't enough to capture the DOM update for the manual refresh only scenario - if (old && !neu) { - this.manualRefreshTimer = setTimeout(() => { - this.watcherUpdateLiveAndDelayed(neu, old); - }, 1000); - } + // setTimeout is needed so that this is pushed further back on the JS computing queue + // because nextTick isn't enough to capture the DOM update for the manual refresh only scenario + if (old && !neu) { + this.manualRefreshTimer = setTimeout(() => { + this.watcherUpdateLiveAndDelayed(neu, old); + }, 1000); + } + }, + immediate: true } }, diff --git a/shell/components/TypeDescription.vue b/shell/components/TypeDescription.vue index 217d9b6d1f..2173e8cb94 100644 --- a/shell/components/TypeDescription.vue +++ b/shell/components/TypeDescription.vue @@ -1,7 +1,9 @@