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

liuxun 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 af259c3a6 [#4362] feat(web): Add GitHub stars and forks number for 
WebUI (#5567)
af259c3a6 is described below

commit af259c3a6981e042490e57c33fb733998b6a1b64
Author: SZL741023 <[email protected]>
AuthorDate: Thu Nov 21 17:29:20 2024 +0800

    [#4362] feat(web): Add GitHub stars and forks number for WebUI (#5567)
    
    ### What changes were proposed in this pull request?
    
    1. Add GitHub image, stars icon and fork icon on the Navbar.
    2. Send GET request to GitHub API to fetch the number of stars and forks
    and show on the Navbar
    3. If the number of stars and forks more than 1000, it will show 1.x k.
    4. Github image and stars icon can link to Gravitino repo, fork icon can
    link to Gravitino fork page.
    5. Position version text next to Gravitino logo.
    
    ### Why are the changes needed?
    
    These change can improve user experience and efficiency.
    
    Fix: #4362
    
    ### Does this PR introduce _any_ user-facing change?
    
    1. Add Github image, stars icon and fork icon.
    2. Position version text next to Gravitino logo.
    
    ### How was this patch tested?
    
    1. Check the data was fetched from GitHub API.
    2. console.log the number more than 1000, manual check it will change to
    1.x k.
    
    
    
![image](https://github.com/user-attachments/assets/1add9bfc-ae53-4492-96ef-c09b84f045a3)
    
    ---------
    
    Co-authored-by: Xun <[email protected]>
    Co-authored-by: Qian Xia <[email protected]>
---
 web/web/public/icons/git-fork.svg                  | 20 ++++++
 web/web/public/icons/github-mark.svg               | 20 ++++++
 web/web/src/app/rootLayout/AppBar.js               |  4 +-
 web/web/src/app/rootLayout/GitHubInfo.js           | 78 ++++++++++++++++++++++
 web/web/src/app/rootLayout/VersionView.js          |  2 +-
 .../VersionView.js => lib/api/github/index.js}     | 24 +++----
 web/web/src/lib/provider/session.js                |  4 +-
 web/web/src/lib/store/sys/index.js                 | 45 +++++++++++--
 web/web/src/lib/utils/index.js                     | 17 +++++
 9 files changed, 192 insertions(+), 22 deletions(-)

diff --git a/web/web/public/icons/git-fork.svg 
b/web/web/public/icons/git-fork.svg
new file mode 100644
index 000000000..0a1d78065
--- /dev/null
+++ b/web/web/public/icons/git-fork.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+-->
+<svg fill="none" height="24" viewBox="0 0 24 24" width="24" 
xmlns="http://www.w3.org/2000/svg";><path d="m17.4142 
11.4142-.5303-.5303zm1.3358-3.4142c0-.41421-.3358-.75-.75-.75s-.75.33579-.75.75zm-12
 0c0-.41421-.33579-.75-.75-.75s-.75.33579-.75.75zm-.16421 
3.4142-.53033.5303zm6.16421.5858c0-.4142-.3358-.75-.75-.75s-.75.3358-.75.75zm-1.5
 4c0 .4142.3358.75.75.75s.75-.3358.75-.75zm-1.25-3.25h4v-1.5h-4zm4 0c.9216 0 
1.6883.0016 2.2945-.0799.6278-.0844 1.1946-.2701 1.65-.7256l-1.0606-1.0606c-.13 
[...]
diff --git a/web/web/public/icons/github-mark.svg 
b/web/web/public/icons/github-mark.svg
new file mode 100644
index 000000000..13ad84ec5
--- /dev/null
+++ b/web/web/public/icons/github-mark.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+-->
+<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg";><path 
fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 
21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 
0-1.141-.08-5.052-.08-9.127-13.59 
2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015
 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 
4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 
0-5.37 [...]
diff --git a/web/web/src/app/rootLayout/AppBar.js 
b/web/web/src/app/rootLayout/AppBar.js
index c4917d58e..1851b6bc4 100644
--- a/web/web/src/app/rootLayout/AppBar.js
+++ b/web/web/src/app/rootLayout/AppBar.js
@@ -41,6 +41,7 @@ import clsx from 'clsx'
 
 import VersionView from './VersionView'
 import LogoutButton from './Logout'
+import GitHubInfo from './GitHubInfo'
 import { useSearchParams } from 'next/navigation'
 import { useRouter } from 'next/navigation'
 import { useAppSelector, useAppDispatch } from '@/lib/hooks/useStore'
@@ -94,6 +95,7 @@ const AppBar = () => {
               >
                 Gravitino
               </Typography>
+              <VersionView />
             </Link>
             <Box className={'app-bar-content-right twc-flex twc-items-center'}>
               <Stack direction='row' spacing={2} alignItems='center'>
@@ -135,7 +137,7 @@ const AppBar = () => {
                     </Select>
                   </FormControl>
                 ) : null}
-                <VersionView />
+                <GitHubInfo />
                 <LogoutButton />
               </Stack>
             </Box>
diff --git a/web/web/src/app/rootLayout/GitHubInfo.js 
b/web/web/src/app/rootLayout/GitHubInfo.js
new file mode 100644
index 000000000..50744302b
--- /dev/null
+++ b/web/web/src/app/rootLayout/GitHubInfo.js
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+import Link from 'next/link'
+import Image from 'next/image'
+import { Box, Typography } from '@mui/material'
+import { Star } from '@mui/icons-material'
+import { useAppSelector } from '@/lib/hooks/useStore'
+
+const GitHubInfo = () => {
+  const githubUrl = 'https://github.com/apache/gravitino'
+  const githubForkUrl = 'https://github.com/apache/gravitino/fork'
+  const githubLogoUrl = (process.env.NEXT_PUBLIC_BASE_PATH ?? '') + 
'/icons/github-mark.svg'
+  const forkLogoUrl = (process.env.NEXT_PUBLIC_BASE_PATH ?? '') + 
'/icons/git-fork.svg'
+  const store = useAppSelector(state => state.sys)
+
+  return (
+    <Box className={'twc-flex  twc-gap-x-3 twc-bg-customs-lightBg twc-px-3 
twc-py-2 twc-rounded-full'}>
+      <Link href={githubUrl}>
+        <Image
+          className={'twc-align-middle'}
+          src={githubLogoUrl}
+          overrideSrc={githubLogoUrl}
+          width={24}
+          height={24}
+          alt='logo'
+        />
+      </Link>
+      <Box className={'twc-flex twc-items-center twc-gap-x-3 twc-ml-2'}>
+        <Link href={githubForkUrl} className={'twc-no-underline  
twc-bg-customs-dark twc-rounded-full '}>
+          <Typography
+            className={
+              'twc-flex twc-items-center twc-gap-2 twc-text-customs-black 
twc-px-2.5 twc-py-1 twc-text-[0.75rem] twc-font-bold'
+            }
+          >
+            <Image
+              className={'twc-align-middle twc-text-customs-white'}
+              src={forkLogoUrl}
+              overrideSrc={forkLogoUrl}
+              width={24}
+              height={24}
+              alt='logo'
+            />
+            {store.forks} Forks
+          </Typography>
+        </Link>
+        <Link href={githubUrl} className={'twc-no-underline  
twc-bg-customs-dark twc-rounded-full '}>
+          <Typography
+            className={
+              'twc-flex twc-items-center twc-gap-2 twc-text-customs-black 
twc-px-2.5 twc-py-1 twc-text-[0.75rem] twc-font-bold'
+            }
+          >
+            <Star className={'twc-text-customs-black'} />
+            {store.stars} Stars
+          </Typography>
+        </Link>
+      </Box>
+    </Box>
+  )
+}
+
+export default GitHubInfo
diff --git a/web/web/src/app/rootLayout/VersionView.js 
b/web/web/src/app/rootLayout/VersionView.js
index 70ba69903..0f3d39b35 100644
--- a/web/web/src/app/rootLayout/VersionView.js
+++ b/web/web/src/app/rootLayout/VersionView.js
@@ -26,7 +26,7 @@ const VersionView = () => {
   const store = useAppSelector(state => state.sys)
 
   return (
-    <Typography variant='subtitle2' id='gravitino_version' 
className={'twc-flex twc-justify-end'}>
+    <Typography variant='subtitle2' id='gravitino_version' 
className={'twc-flex twc-justify-end twc-ml-2'}>
       {store.version}
     </Typography>
   )
diff --git a/web/web/src/app/rootLayout/VersionView.js 
b/web/web/src/lib/api/github/index.js
similarity index 68%
copy from web/web/src/app/rootLayout/VersionView.js
copy to web/web/src/lib/api/github/index.js
index 70ba69903..456316221 100644
--- a/web/web/src/app/rootLayout/VersionView.js
+++ b/web/web/src/lib/api/github/index.js
@@ -16,20 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-'use client'
 
-import { Typography } from '@mui/material'
+import { defHttp } from '@/lib/utils/axios'
 
-import { useAppSelector } from '@/lib/hooks/useStore'
-
-const VersionView = () => {
-  const store = useAppSelector(state => state.sys)
-
-  return (
-    <Typography variant='subtitle2' id='gravitino_version' 
className={'twc-flex twc-justify-end'}>
-      {store.version}
-    </Typography>
-  )
+const githubApis = {
+  GET: 'https://api.github.com/repos/apache/gravitino'
 }
 
-export default VersionView
+export const getGitHubApi = () => {
+  return defHttp.get({
+    url: `${githubApis.GET}`,
+    headers: {
+      Accept: 'application/vnd.github+json'
+    }
+  })
+}
diff --git a/web/web/src/lib/provider/session.js 
b/web/web/src/lib/provider/session.js
index 1c9858f99..5247987c2 100644
--- a/web/web/src/lib/provider/session.js
+++ b/web/web/src/lib/provider/session.js
@@ -25,7 +25,7 @@ import { useRouter } from 'next/navigation'
 import { useSearchParams } from 'next/navigation'
 
 import { useAppDispatch } from '@/lib/hooks/useStore'
-import { initialVersion } from '@/lib/store/sys'
+import { initialVersion, fetchGitHubInfo } from '@/lib/store/sys'
 
 import { to } from '../utils'
 import { getAuthConfigs, setAuthToken } from '../store/auth'
@@ -78,11 +78,13 @@ const AuthProvider = ({ children }) => {
 
       if (authType === 'simple') {
         dispatch(initialVersion())
+        dispatch(fetchGitHubInfo())
         goToMetalakeListPage()
       } else if (authType === 'oauth') {
         if (token) {
           dispatch(setAuthToken(token))
           dispatch(initialVersion())
+          dispatch(fetchGitHubInfo())
           goToMetalakeListPage()
         } else {
           router.push('/login')
diff --git a/web/web/src/lib/store/sys/index.js 
b/web/web/src/lib/store/sys/index.js
index 475063f8a..cb7eb6050 100644
--- a/web/web/src/lib/store/sys/index.js
+++ b/web/web/src/lib/store/sys/index.js
@@ -19,10 +19,12 @@
 
 import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
 
-import { loggerVersion, to } from '@/lib/utils'
+import { loggerVersion, to, formatNumber, loggerGitHubInfo } from '@/lib/utils'
 
 import { getVersionApi } from '@/lib/api/version'
 
+import { getGitHubApi } from '@/lib/api/github'
+
 export const initialVersion = createAsyncThunk('sys/fetchVersion', async 
(params, { getState }) => {
   let version = null
   const [err, res] = await to(getVersionApi())
@@ -39,23 +41,54 @@ export const initialVersion = 
createAsyncThunk('sys/fetchVersion', async (params
   return version
 })
 
+export const fetchGitHubInfo = createAsyncThunk('sys/fetchGitHubInfo', async 
(params, { getState }) => {
+  let stars = 0
+  let forks = 0
+  const [err, res] = await to(getGitHubApi())
+  if (err || !res) {
+    console.error('Error fetching repository status : ', err)
+  }
+
+  stars = formatNumber(res.stargazers_count)
+  forks = formatNumber(res.forks_count)
+  loggerGitHubInfo(stars, forks)
+
+  return {
+    stars: stars,
+    forks: forks
+  }
+})
+
 export const sysSlice = createSlice({
   name: 'sys',
   initialState: {
-    version: ''
+    version: '',
+    stars: 0,
+    forks: 0
   },
   reducers: {
     setVersion(state, action) {
       state.version = action.payload
+    },
+    setStars(state, action) {
+      state.stars = action.payload
+    },
+    setForks(state, action) {
+      state.forks = action.payload
     }
   },
   extraReducers: builder => {
-    builder.addCase(initialVersion.fulfilled, (state, action) => {
-      state.version = action.payload.version
-    })
+    builder
+      .addCase(initialVersion.fulfilled, (state, action) => {
+        state.version = action.payload.version
+      })
+      .addCase(fetchGitHubInfo.fulfilled, (state, action) => {
+        state.stars = action.payload.stars
+        state.forks = action.payload.forks
+      })
   }
 })
 
-export const { setVersion } = sysSlice.actions
+export const { setVersion, setStars, setForks } = sysSlice.actions
 
 export default sysSlice.reducer
diff --git a/web/web/src/lib/utils/index.js b/web/web/src/lib/utils/index.js
index 17444dfa8..8b41db98a 100644
--- a/web/web/src/lib/utils/index.js
+++ b/web/web/src/lib/utils/index.js
@@ -45,6 +45,13 @@ export const loggerVersion = version => {
   )
 }
 
+export const loggerGitHubInfo = (stars, forks) => {
+  console.log(
+    `Gravitino GitHubInfo: %c Stars ${stars}, Forks ${forks}`,
+    `color: white; background-color: #6062E0; padding: 2px; border-radius: 
4px;`
+  )
+}
+
 export const genUpdates = (originalData, newData) => {
   const updates = []
 
@@ -227,3 +234,13 @@ export const findInTree = (tree, key, value) => {
 
   return result
 }
+
+export const formatNumber = num => {
+  if (num >= 1000000) {
+    return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'm'
+  } else if (num >= 1000) {
+    return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'k'
+  }
+
+  return num.toString()
+}

Reply via email to