This is an automated email from the ASF dual-hosted git repository.

jerryshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new f350927f96 [#12289] web-v2(UI): fix about retains the previous 
sub-path when switching filesets (#12292)
f350927f96 is described below

commit f350927f9626cfd1eed3102da5ef31d5f0c406fb
Author: Qian Xia <[email protected]>
AuthorDate: Mon Aug 3 17:27:02 2026 +0800

    [#12289] web-v2(UI): fix about retains the previous sub-path when switching 
filesets (#12292)
    
    ### What changes were proposed in this pull request?
    
    1. page.js — Add resetActivatedDetails() for the fileset branch
    (consistent with the table branch), clearing stale activatedDetails
    before loading new data.
    
    2. FilesetDetailsPage.js — Guard ListFiles rendering with
    !store.activatedDetailsLoading to prevent mounting before new details
    are ready.
    
    3. ListFiles.js — Three fixes:
    - Render-time reset: Detect filesetIdentity change via useRef and reset
    sub_path/currentLocation immediately during render (before useEffects
    run).
    - Stale props detection: Track which fileset the storageLocations prop
    belongs to. Block API calls and show loading spinner when
    storageLocations is stale.
    - currentLocation sync: Derive currentLocation from
    storageLocations/defaultLocationName when it's undefined or invalid,
    instead of blindly trusting the previous value.
    
    
    ### Why are the changes needed?
    
    
    Fix: #12289
    
    ### Does this PR introduce _any_ user-facing change?
    
    N/A
    
    ### How was this patch tested?
    munaully
---
 web-v2/web/src/app/catalogs/page.js                |  1 +
 .../entitiesContent/FilesetDetailsPage.js          |  3 +-
 .../rightContent/entitiesContent/ListFiles.js      | 42 +++++++++++++---------
 3 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/web-v2/web/src/app/catalogs/page.js 
b/web-v2/web/src/app/catalogs/page.js
index 9e8b2e5b3a..9aeecc3705 100644
--- a/web-v2/web/src/app/catalogs/page.js
+++ b/web-v2/web/src/app/catalogs/page.js
@@ -253,6 +253,7 @@ const CatalogsListPage = () => {
               case 'fileset':
                 store.filesets.length === 0 &&
                   (await dispatch(fetchFilesets({ init: true, page: 'schemas', 
metalake, catalog, schema })))
+                await dispatch(resetActivatedDetails())
                 await dispatch(setActivatedDetailsLoading(true))
                 await dispatch(getFilesetDetails({ init: true, metalake, 
catalog, schema, fileset }))
                 await dispatch(setActivatedDetailsLoading(false))
diff --git 
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/FilesetDetailsPage.js
 
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/FilesetDetailsPage.js
index ad34e2136c..f6289ac64d 100644
--- 
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/FilesetDetailsPage.js
+++ 
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/FilesetDetailsPage.js
@@ -265,9 +265,10 @@ export default function FilesetDetailsPage({ ...props }) {
         </Space>
       </Spin>
       <Tabs items={tabOptions} activeKey={activeTab} onChange={setActiveTab} />
-      {activeTab === 'files' && (
+      {activeTab === 'files' && !store.activatedDetailsLoading && (
         <div data-refer='tab-files-panel'>
           <ListFiles
+            key={`${catalog}.${schema}.${fileset}`}
             metalake={currentMetalake}
             catalog={catalog}
             schema={schema}
diff --git 
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/ListFiles.js 
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/ListFiles.js
index 3fd84ba3f9..ed6cc4d84d 100644
--- a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/ListFiles.js
+++ b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/ListFiles.js
@@ -41,11 +41,28 @@ const ListFiles = ({ metalake, catalog, schema, fileset, 
storageLocations, defau
   const store = useAppSelector(state => state.metalakes)
   const dispatch = useAppDispatch()
 
+  // Sync currentLocation with storageLocations/defaultLocationName.
+  // When currentLocation is undefined or no longer exists in
+  // storageLocations, derive the correct value from props.
   useEffect(() => {
-    if (defaultLocationName) {
+    if (!storageLocations || Object.keys(storageLocations).length === 0) {
+      setCurrentLocation(undefined)
+
+      return
+    }
+
+    // If currentLocation is valid in current storageLocations, keep it
+    if (currentLocation && storageLocations[currentLocation]) {
+      return
+    }
+
+    // Otherwise, derive from props
+    if (defaultLocationName && storageLocations[defaultLocationName]) {
       setCurrentLocation(defaultLocationName)
+    } else {
+      setCurrentLocation(Object.keys(storageLocations)[0])
     }
-  }, [defaultLocationName])
+  }, [currentLocation, defaultLocationName, storageLocations])
 
   useEffect(() => {
     if (sub_path) {
@@ -56,7 +73,7 @@ const ListFiles = ({ metalake, catalog, schema, fileset, 
storageLocations, defau
   }, [sub_path])
 
   useEffect(() => {
-    if (metalake && catalog && schema && fileset) {
+    if (metalake && catalog && schema && fileset && currentLocation && 
storageLocations?.[currentLocation]) {
       dispatch(
         getFilesetFiles({
           metalake,
@@ -149,25 +166,16 @@ const ListFiles = ({ metalake, catalog, schema, fileset, 
storageLocations, defau
     return { columns, minWidth: 100 }
   }, [columns])
 
-  if (!storageLocations || Object.keys(storageLocations).length === 0) {
-    return <p>No storage locations configured</p>
-  }
-
-  if (!currentLocation && defaultLocationName) {
-    setCurrentLocation(defaultLocationName)
-
+  if (!storageLocations) {
     return <Spin />
   }
 
-  if (!currentLocation && Object.keys(storageLocations).length > 0) {
-    const firstLocation = Object.keys(storageLocations)[0]
-    setCurrentLocation(firstLocation)
-
-    return <Spin />
+  if (Object.keys(storageLocations).length === 0) {
+    return <Text type='secondary'>No storage locations configured</Text>
   }
 
-  if (!currentLocation) {
-    return <p>Please select a storage location</p>
+  if (!currentLocation || !storageLocations[currentLocation]) {
+    return <Spin />
   }
 
   const displayedFiles = [...store.tableData] || []

Reply via email to