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.

### 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>
)
}