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

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


The following commit(s) were added to refs/heads/branch-1.3 by this push:
     new b7b19fea22 [Cherry-pick to branch-1.3] [#12200] fix(web-v2): Gate 
metalake fetch until OAuth token is ready (#12203) (#12251)
b7b19fea22 is described below

commit b7b19fea2286ebcff104535ea02d912316086aa3
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Jul 31 18:11:02 2026 +0800

    [Cherry-pick to branch-1.3] [#12200] fix(web-v2): Gate metalake fetch until 
OAuth token is ready (#12203) (#12251)
    
    **Cherry-pick Information:**
    - Original commit: 29d40aa6404606b0caf99dcbf9366854f2cacfea
    - Target branch: `branch-1.3`
    - Status: ⚠️ **Has conflicts - manual resolution required**
    
    Please review and resolve the conflicts before merging.
    
    ---------
    
    Co-authored-by: Phước <[email protected]>
    Co-authored-by: phuocho <[email protected]>
    Co-authored-by: Qian Xia <[email protected]>
---
 web-v2/web/src/app/metalakes/page.js         | 12 +++++++++--
 web-v2/web/src/app/rootLayout/SiteHeader.js  |  8 +++++++-
 web-v2/web/src/app/rootLayout/UserSetting.js |  7 ++++++-
 web-v2/web/src/lib/store/metalakes/index.js  | 30 +++++++++++++++++++---------
 4 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/web-v2/web/src/app/metalakes/page.js 
b/web-v2/web/src/app/metalakes/page.js
index 183b04a329..f1d0c684f4 100644
--- a/web-v2/web/src/app/metalakes/page.js
+++ b/web-v2/web/src/app/metalakes/page.js
@@ -69,7 +69,8 @@ const MetalakeList = () => {
   const [search, setSearch] = useState('')
   const [ownerRefreshKey, setOwnerRefreshKey] = useState(0)
   const auth = useAppSelector(state => state.auth)
-  const { serviceAdmins, authUser, anthEnable } = auth
+  const { serviceAdmins, authUser, anthEnable, authType, authToken } = auth
+  const isAuthReady = authType && (authType !== 'oauth' || !!authToken)
   const admins = Array.isArray(serviceAdmins) ? serviceAdmins : (serviceAdmins 
|| '').split(',')
   const isServiceAdmin = admins.includes(authUser?.name)
   const dispatch = useAppDispatch()
@@ -78,9 +79,16 @@ const MetalakeList = () => {
 
   useEffect(() => {
     dispatch(resetMetalakeStore())
-    dispatch(fetchMetalakes())
   }, [dispatch])
 
+  useEffect(() => {
+    if (!isAuthReady) {
+      return
+    }
+
+    dispatch(fetchMetalakes())
+  }, [dispatch, isAuthReady])
+
   useEffect(() => {
     const filteredData = store.metalakes
       .filter(i => i.name.toLowerCase().includes(search.toLowerCase()))
diff --git a/web-v2/web/src/app/rootLayout/SiteHeader.js 
b/web-v2/web/src/app/rootLayout/SiteHeader.js
index a6133f23ca..f23939b517 100644
--- a/web-v2/web/src/app/rootLayout/SiteHeader.js
+++ b/web-v2/web/src/app/rootLayout/SiteHeader.js
@@ -38,12 +38,18 @@ export function SiteHeader() {
 
   const dispatch = useAppDispatch()
   const store = useAppSelector(state => state.metalakes)
+  const auth = useAppSelector(state => state.auth)
+  const isAuthReady = !!auth.authType && (auth.authType !== 'oauth' || 
!!auth.authToken)
 
   useEffect(() => {
+    if (!isAuthReady) {
+      return
+    }
+
     if (pathname && !['/', '/ui', '/login', '/ui/login', '/oauth/callback', 
'/ui/oauth/callback'].includes(pathname)) {
       dispatch(fetchMetalakes())
     }
-  }, [dispatch, pathname])
+  }, [dispatch, pathname, isAuthReady])
 
   // Ensure URL has sensible defaults when missing:
   // - When not on `/metalakes` and `metalake` query is 
missing/empty/"undefined",
diff --git a/web-v2/web/src/app/rootLayout/UserSetting.js 
b/web-v2/web/src/app/rootLayout/UserSetting.js
index d3041ae2a8..23a4c326bf 100644
--- a/web-v2/web/src/app/rootLayout/UserSetting.js
+++ b/web-v2/web/src/app/rootLayout/UserSetting.js
@@ -50,12 +50,17 @@ export default function UserSetting() {
   const currentMetalake = searchParams.get('metalake')
   const dispatch = useAppDispatch()
   const store = useAppSelector(state => state.metalakes)
+  const isAuthReady = !!auth.authType && (auth.authType !== 'oauth' || 
!!auth.authToken)
 
   useEffect(() => {
+    if (!isAuthReady) {
+      return
+    }
+
     if (pathname && !['/', '/ui', '/login', '/ui/login', '/oauth/callback', 
'/ui/oauth/callback'].includes(pathname)) {
       dispatch(fetchMetalakes())
     }
-  }, [dispatch, pathname])
+  }, [dispatch, pathname, isAuthReady])
 
   const handleCreateMetalake = () => {
     setOpenCreateMeta(true)
diff --git a/web-v2/web/src/lib/store/metalakes/index.js 
b/web-v2/web/src/lib/store/metalakes/index.js
index 2f6cd2c4a5..55566d6973 100644
--- a/web-v2/web/src/lib/store/metalakes/index.js
+++ b/web-v2/web/src/lib/store/metalakes/index.js
@@ -108,19 +108,31 @@ const mergeWithViewNodes = ({ tree, key, entities }) => {
   return _.uniqBy([...subSchemas, ...tables, ...functions, ...entities], 'key')
 }
 
-export const fetchMetalakes = createAsyncThunk('appMetalakes/fetchMetalakes', 
async (params, { getState }) => {
-  const [err, res] = await to(getMetalakesApi())
+const isAuthReady = state => {
+  const { authType, authToken } = state.auth
 
-  if (err || !res) {
-    throw new Error(err)
-  }
+  return !!authType && (authType !== 'oauth' || !!authToken)
+}
 
-  const { metalakes } = res
+export const fetchMetalakes = createAsyncThunk(
+  'appMetalakes/fetchMetalakes',
+  async () => {
+    const [err, res] = await to(getMetalakesApi())
 
-  metalakes.sort((a, b) => new Date(b.audit.createTime) - new 
Date(a.audit.createTime))
+    if (err || !res) {
+      throw new Error(err)
+    }
 
-  return { metalakes }
-})
+    const { metalakes } = res
+
+    metalakes.sort((a, b) => new Date(b.audit.createTime) - new 
Date(a.audit.createTime))
+
+    return { metalakes }
+  },
+  {
+    condition: (_, { getState }) => isAuthReady(getState())
+  }
+)
 
 export const createMetalake = createAsyncThunk('appMetalakes/createMetalake', 
async (data, { getState, dispatch }) => {
   const [err, res] = await to(createMetalakeApi(data))

Reply via email to