This is an automated email from the ASF dual-hosted git repository.
LauraXia123 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 64009ee93c [MINOR] fix(web-v2): Normalize service admins configuration
(#12046)
64009ee93c is described below
commit 64009ee93c770d0b99cea5053ce5840924afff8d
Author: gaohong <[email protected]>
AuthorDate: Fri Jul 17 13:57:48 2026 +0800
[MINOR] fix(web-v2): Normalize service admins configuration (#12046)
### What changes were proposed in this pull request?
This PR adds a shared `normalizeServiceAdmins` utility and uses it in
the Metalake list page and user settings component.
The utility normalizes `serviceAdmins` into an array and supports both
formats returned by the configuration API:
- An array of user names
- A comma-separated string of user names
Unsupported values are normalized to an empty array.
### Why are the changes needed?
`serviceAdmins` can be returned as either an array or a comma-separated
string. The previous duplicated page-level logic could call
`.split(',')` on a non-string value, causing a frontend runtime error.
This change centralizes the normalization logic and prevents the UI from
failing when the configuration value has an unexpected type.
Fix: N/A
### Does this PR introduce _any_ user-facing change?
Yes. The UI now handles both supported `serviceAdmins` formats
consistently and no longer fails for unsupported values.
No user-facing API or configuration property is added or changed.
### How was this patch tested?
- Ran `git diff --check upstream/main...HEAD`.
- Verified that both existing `serviceAdmins` consumers use the shared
utility:
- `web-v2/web/src/app/rootLayout/UserSetting.js`
- `web-v2/web/src/app/metalakes/page.js`
No automated frontend tests were run.
Co-authored-by: gaohong <[email protected]>
---
web-v2/web/src/app/metalakes/page.js | 3 ++-
web-v2/web/src/app/rootLayout/UserSetting.js | 3 ++-
web-v2/web/src/lib/utils/serviceAdmins.js | 30 ++++++++++++++++++++++++++++
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/web-v2/web/src/app/metalakes/page.js
b/web-v2/web/src/app/metalakes/page.js
index 183b04a329..1f9c468846 100644
--- a/web-v2/web/src/app/metalakes/page.js
+++ b/web-v2/web/src/app/metalakes/page.js
@@ -37,6 +37,7 @@ import {
} from '@/lib/store/metalakes'
import { to } from '@/lib/utils'
import { formatToDateTime } from '@/lib/utils/date'
+import { normalizeServiceAdmins } from '@/lib/utils/serviceAdmins'
import Icons from '@/components/Icons'
import GetOwner from '@/components/GetOwner'
import PropertiesContent from '@/components/PropertiesContent'
@@ -70,7 +71,7 @@ const MetalakeList = () => {
const [ownerRefreshKey, setOwnerRefreshKey] = useState(0)
const auth = useAppSelector(state => state.auth)
const { serviceAdmins, authUser, anthEnable } = auth
- const admins = Array.isArray(serviceAdmins) ? serviceAdmins : (serviceAdmins
|| '').split(',')
+ const admins = normalizeServiceAdmins(serviceAdmins)
const isServiceAdmin = admins.includes(authUser?.name)
const dispatch = useAppDispatch()
const store = useAppSelector(state => state.metalakes)
diff --git a/web-v2/web/src/app/rootLayout/UserSetting.js
b/web-v2/web/src/app/rootLayout/UserSetting.js
index d3041ae2a8..a4a8fc251e 100644
--- a/web-v2/web/src/app/rootLayout/UserSetting.js
+++ b/web-v2/web/src/app/rootLayout/UserSetting.js
@@ -24,6 +24,7 @@ import { LogoutOutlined, PlusOutlined, UserOutlined } from
'@ant-design/icons'
import { Avatar, Dropdown, Tooltip } from 'antd'
import { usePathname, useSearchParams, useRouter } from 'next/navigation'
import { cn } from '@/lib/utils/tailwind'
+import { normalizeServiceAdmins } from '@/lib/utils/serviceAdmins'
import { useAppSelector, useAppDispatch } from '@/lib/hooks/useStore'
import Loading from '@/components/Loading'
import { fetchMetalakes, resetMetalakeStore } from '@/lib/store/metalakes'
@@ -41,7 +42,7 @@ export default function UserSetting() {
const [showLogoutButton, setShowLogoutButton] = useState(false)
const auth = useAppSelector(state => state.auth)
const { serviceAdmins, authUser, anthEnable } = auth
- const admins = Array.isArray(serviceAdmins) ? serviceAdmins : (serviceAdmins
|| '').split(',')
+ const admins = normalizeServiceAdmins(serviceAdmins)
const isServiceAdmin = admins.includes(authUser?.name)
const [session, setSession] = useState({})
const router = useRouter()
diff --git a/web-v2/web/src/lib/utils/serviceAdmins.js
b/web-v2/web/src/lib/utils/serviceAdmins.js
new file mode 100644
index 0000000000..43717f9471
--- /dev/null
+++ b/web-v2/web/src/lib/utils/serviceAdmins.js
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export const normalizeServiceAdmins = serviceAdmins => {
+ if (Array.isArray(serviceAdmins)) {
+ return serviceAdmins
+ }
+
+ if (typeof serviceAdmins === 'string') {
+ return serviceAdmins.split(',')
+ }
+
+ return []
+}