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

jshao 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 239c500845 [#6592] improvement(web): Add copy-to-clipboard button for 
identity string (#7182)
239c500845 is described below

commit 239c500845a47d31f3e0a44dae6d5d7afb53cc80
Author: Kyle Lin <[email protected]>
AuthorDate: Mon May 19 16:51:33 2025 +0800

    [#6592] improvement(web): Add copy-to-clipboard button for identity string 
(#7182)
    
    ### What changes were proposed in this pull request?
    
    - Added a new button on the frontend UI that allows users to easily copy
    the identity information of a table.
    - While running `pnpm prettier . --check`, some formatting in
    `MetalakePath.js` was automatically adjusted.
    - Fixed a typo as well.
    
    ### Why are the changes needed?
    
    Fixes #6592
    
    ### Does this PR introduce any user-facing change?
    
    Yes. Users can now quickly copy the identity string of a table using the
    new button.
    
    ![Add copy-to-clipboard button for identity
    
string](https://github.com/user-attachments/assets/220493e2-b2ad-4641-a676-b5e7a5f09007)
    
    ### How was this patch tested?
    
    - Ran `pnpm prettier . --check`
    - Ran `./gradlew clean build`.
---
 .../metalake/rightContent/MetalakePath.js          | 238 +++++++++++----------
 1 file changed, 129 insertions(+), 109 deletions(-)

diff --git a/web/web/src/app/metalakes/metalake/rightContent/MetalakePath.js 
b/web/web/src/app/metalakes/metalake/rightContent/MetalakePath.js
index 9f41ccc0eb..9deeff5375 100644
--- a/web/web/src/app/metalakes/metalake/rightContent/MetalakePath.js
+++ b/web/web/src/app/metalakes/metalake/rightContent/MetalakePath.js
@@ -22,12 +22,12 @@
 import Link from 'next/link'
 import { useSearchParams } from 'next/navigation'
 
-import { Link as MUILink, Breadcrumbs, Typography, Tooltip, styled } from 
'@mui/material'
+import { Link as MUILink, Breadcrumbs, Typography, Tooltip, styled, Box, 
IconButton } from '@mui/material'
 
 import Icon from '@/components/Icon'
 
 const TextWrapper = styled(Typography)(({ theme }) => ({
-  mixWidth: '120px',
+  maxWidth: '120px',
   overflow: 'hidden',
   textOverflow: 'ellipsis',
   whiteSpace: 'nowrap'
@@ -67,117 +67,137 @@ const MetalakePath = props => {
     path === `?${searchParams.toString()}` && event.preventDefault()
   }
 
+  const identity = [metalake, catalog, schema, table ?? fileset ?? topic ?? 
model].filter(Boolean).join('.')
+
+  const handleCopy = async () => {
+    if (identity) {
+      if (navigator.clipboard && navigator.clipboard.writeText) await 
navigator.clipboard.writeText(identity)
+      else console.warn('Clipboard API not available')
+    }
+  }
+
   return (
-    <Breadcrumbs
-      sx={{
-        width: 'calc(100% - 48px)',
-        overflow: 'hidden',
-        mt: 0,
-        '& a': { display: 'flex', alignItems: 'center' },
-        '& ol': {
-          flexWrap: 'nowrap'
-        },
-        '& ol > li.MuiBreadcrumbs-li': {
+    <Box width='calc(100% - 48px)' display='flex' alignItems='center' gap={1}>
+      <Breadcrumbs
+        sx={{
           overflow: 'hidden',
-          display: 'inline-flex',
-          '& > a': {
-            width: '100%',
-            '& > svg': {
-              minWidth: 20
+          mt: 0,
+          '& a': { display: 'flex', alignItems: 'center' },
+          '& ol': {
+            flexWrap: 'nowrap'
+          },
+          '& ol > li.MuiBreadcrumbs-li': {
+            overflow: 'hidden',
+            display: 'inline-flex',
+            '& > a': {
+              width: '100%',
+              '& > svg': {
+                minWidth: 20
+              }
             }
+          },
+          '& ol > li:last-of-type': {
+            color: theme => `${theme.palette.text.primary} !important`,
+            overflow: 'hidden'
           }
-        },
-        '& ol > li:last-of-type': {
-          color: theme => `${theme.palette.text.primary} !important`,
-          overflow: 'hidden'
-        }
-      }}
-    >
-      {metalake && (
-        <Tooltip title={metalake} placement='top'>
-          <MUILink
-            component={Link}
-            href={metalakeUrl}
-            onClick={event => handleClick(event, metalakeUrl)}
-            underline='hover'
-            data-refer='metalake-name-link'
-          >
-            <Text>{metalake}</Text>
-          </MUILink>
-        </Tooltip>
-      )}
-      {catalog && (
-        <Tooltip title={catalog} placement='top'>
-          <MUILink
-            component={Link}
-            href={catalogUrl}
-            onClick={event => handleClick(event, catalogUrl)}
-            underline='hover'
-          >
-            <Icon icon='bx:book' fontSize={20} />
-            <Text data-refer={`nav-to-catalog-${catalog}`}>{catalog}</Text>
-          </MUILink>
-        </Tooltip>
-      )}
-      {schema && (
-        <Tooltip title={schema} placement='top'>
-          <MUILink component={Link} href={schemaUrl} onClick={event => 
handleClick(event, schemaUrl)} underline='hover'>
-            <Icon icon='bx:coin-stack' fontSize={20} />
-            <Text data-refer={`nav-to-schema-${schema}`}>{schema}</Text>
-          </MUILink>
-        </Tooltip>
-      )}
-      {table && (
-        <Tooltip title={table} placement='top'>
-          <MUILink component={Link} href={tableUrl} onClick={event => 
handleClick(event, tableUrl)} underline='hover'>
-            <Icon icon='bx:table' fontSize={20} />
-            <Text data-refer={`nav-to-table-${table}`}>{table}</Text>
-          </MUILink>
-        </Tooltip>
-      )}
-      {fileset && (
-        <Tooltip title={fileset} placement='top'>
-          <MUILink
-            component={Link}
-            href={filesetUrl}
-            onClick={event => handleClick(event, filesetUrl)}
-            underline='hover'
-          >
-            <Icon icon='bx:file' fontSize={20} />
-            <Text>{fileset}</Text>
-          </MUILink>
-        </Tooltip>
-      )}
-      {topic && (
-        <Tooltip title={topic} placement='top'>
-          <MUILink component={Link} href={topicUrl} onClick={event => 
handleClick(event, topicUrl)} underline='hover'>
-            <Icon icon='bx:file' fontSize={20} />
-            <Text>{topic}</Text>
-          </MUILink>
-        </Tooltip>
-      )}
-      {model && (
-        <Tooltip title={model} placement='top'>
-          <MUILink component={Link} href={modelUrl} onClick={event => 
handleClick(event, modelUrl)} underline='hover'>
-            <Icon icon='bx:file' fontSize={20} />
-            <Text>{model}</Text>
-          </MUILink>
-        </Tooltip>
-      )}
-      {version && (
-        <Tooltip title={version} placement='top'>
-          <MUILink
-            component={Link}
-            href={versionUrl}
-            onClick={event => handleClick(event, versionUrl)}
-            underline='hover'
-          >
-            <Icon icon='bx:file' fontSize={20} />
-            <Text>{version}</Text>
-          </MUILink>
-        </Tooltip>
-      )}
-    </Breadcrumbs>
+        }}
+      >
+        {metalake && (
+          <Tooltip title={metalake} placement='top'>
+            <MUILink
+              component={Link}
+              href={metalakeUrl}
+              onClick={event => handleClick(event, metalakeUrl)}
+              underline='hover'
+              data-refer='metalake-name-link'
+            >
+              <Text>{metalake}</Text>
+            </MUILink>
+          </Tooltip>
+        )}
+        {catalog && (
+          <Tooltip title={catalog} placement='top'>
+            <MUILink
+              component={Link}
+              href={catalogUrl}
+              onClick={event => handleClick(event, catalogUrl)}
+              underline='hover'
+            >
+              <Icon icon='bx:book' fontSize={20} />
+              <Text data-refer={`nav-to-catalog-${catalog}`}>{catalog}</Text>
+            </MUILink>
+          </Tooltip>
+        )}
+        {schema && (
+          <Tooltip title={schema} placement='top'>
+            <MUILink
+              component={Link}
+              href={schemaUrl}
+              onClick={event => handleClick(event, schemaUrl)}
+              underline='hover'
+            >
+              <Icon icon='bx:coin-stack' fontSize={20} />
+              <Text data-refer={`nav-to-schema-${schema}`}>{schema}</Text>
+            </MUILink>
+          </Tooltip>
+        )}
+        {table && (
+          <Tooltip title={table} placement='top'>
+            <MUILink component={Link} href={tableUrl} onClick={event => 
handleClick(event, tableUrl)} underline='hover'>
+              <Icon icon='bx:table' fontSize={20} />
+              <Text data-refer={`nav-to-table-${table}`}>{table}</Text>
+            </MUILink>
+          </Tooltip>
+        )}
+        {fileset && (
+          <Tooltip title={fileset} placement='top'>
+            <MUILink
+              component={Link}
+              href={filesetUrl}
+              onClick={event => handleClick(event, filesetUrl)}
+              underline='hover'
+            >
+              <Icon icon='bx:file' fontSize={20} />
+              <Text>{fileset}</Text>
+            </MUILink>
+          </Tooltip>
+        )}
+        {topic && (
+          <Tooltip title={topic} placement='top'>
+            <MUILink component={Link} href={topicUrl} onClick={event => 
handleClick(event, topicUrl)} underline='hover'>
+              <Icon icon='bx:file' fontSize={20} />
+              <Text>{topic}</Text>
+            </MUILink>
+          </Tooltip>
+        )}
+        {model && (
+          <Tooltip title={model} placement='top'>
+            <MUILink component={Link} href={modelUrl} onClick={event => 
handleClick(event, modelUrl)} underline='hover'>
+              <Icon icon='bx:file' fontSize={20} />
+              <Text>{model}</Text>
+            </MUILink>
+          </Tooltip>
+        )}
+        {version && (
+          <Tooltip title={version} placement='top'>
+            <MUILink
+              component={Link}
+              href={versionUrl}
+              onClick={event => handleClick(event, versionUrl)}
+              underline='hover'
+            >
+              <Icon icon='bx:file' fontSize={20} />
+              <Text>{version}</Text>
+            </MUILink>
+          </Tooltip>
+        )}
+      </Breadcrumbs>
+      <Tooltip title='Copy identity string'>
+        <IconButton size='small' onClick={handleCopy}>
+          <Icon icon='bx:copy' fontSize={20} />
+        </IconButton>
+      </Tooltip>
+    </Box>
   )
 }
 

Reply via email to