MINOR: open links in new tab in DataAssetsHeader (#18172)

* MINOR: open links in new tab in DataAssetsHeader

* fix: make mlModelDetail.dashboard internal link
This commit is contained in:
fuzmish 2024-10-09 14:25:51 +09:00 committed by GitHub
parent e1c3ccfa72
commit dc24c00b8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 45 additions and 2 deletions

View File

@ -107,10 +107,12 @@ export const ExtraInfoLink = ({
label, label,
value, value,
href, href,
newTab = false,
}: { }: {
label: string; label: string;
value: string | number; value: string | number;
href: string; href: string;
newTab?: boolean;
}) => ( }) => (
<> <>
<Divider className="self-center" type="vertical" /> <Divider className="self-center" type="vertical" />
@ -118,7 +120,11 @@ export const ExtraInfoLink = ({
{!isEmpty(label) && ( {!isEmpty(label) && (
<span className="text-grey-muted m-r-xss">{`${label}: `}</span> <span className="text-grey-muted m-r-xss">{`${label}: `}</span>
)} )}
<Typography.Link href={href} style={{ fontSize: '12px' }}> <Typography.Link
href={href}
rel={newTab ? 'noopener noreferrer' : undefined}
style={{ fontSize: '12px' }}
target={newTab ? '_blank' : undefined}>
{value}{' '} {value}{' '}
</Typography.Link> </Typography.Link>
<Icon <Icon

View File

@ -21,7 +21,7 @@ import { Container } from '../../../generated/entity/data/container';
import { MOCK_TIER_DATA } from '../../../mocks/TableData.mock'; import { MOCK_TIER_DATA } from '../../../mocks/TableData.mock';
import { getContainerByName } from '../../../rest/storageAPI'; import { getContainerByName } from '../../../rest/storageAPI';
import { DEFAULT_ENTITY_PERMISSION } from '../../../utils/PermissionsUtils'; import { DEFAULT_ENTITY_PERMISSION } from '../../../utils/PermissionsUtils';
import { DataAssetsHeader } from './DataAssetsHeader.component'; import { DataAssetsHeader, ExtraInfoLink } from './DataAssetsHeader.component';
import { DataAssetsHeaderProps } from './DataAssetsHeader.interface'; import { DataAssetsHeaderProps } from './DataAssetsHeader.interface';
const mockProps: DataAssetsHeaderProps = { const mockProps: DataAssetsHeaderProps = {
@ -103,6 +103,37 @@ jest.mock('../../../rest/storageAPI', () => ({
.mockImplementation(() => Promise.resolve({ name: 'test' })), .mockImplementation(() => Promise.resolve({ name: 'test' })),
})); }));
describe('ExtraInfoLink component', () => {
const mockProps = {
label: 'myLabel',
value: 'example',
href: 'http://example.com/',
};
it('should not have target and rel attributes when newTab is false (default)', () => {
const { container } = render(<ExtraInfoLink {...mockProps} />);
const elm = container.querySelector('a');
expect(elm).toHaveAttribute('href', mockProps.href);
expect(elm).not.toHaveAttribute('target');
expect(elm).not.toHaveAttribute('rel');
});
it('should have target and rel attributes when newTab is true', () => {
const { container } = render(<ExtraInfoLink {...mockProps} newTab />);
const elm = container.querySelector('a');
expect(elm).toHaveAttribute('href', mockProps.href);
expect(elm).toHaveAttribute('target', '_blank');
const rel = (elm?.getAttribute('rel') || '').split(/\s+/g);
expect(rel.sort()).toStrictEqual(['noopener', 'noreferrer'].sort());
});
});
describe('DataAssetsHeader component', () => { describe('DataAssetsHeader component', () => {
it('should call getContainerByName API on Page load for container assets', () => { it('should call getContainerByName API on Page load for container assets', () => {
const mockGetContainerByName = getContainerByName as jest.Mock; const mockGetContainerByName = getContainerByName as jest.Mock;

View File

@ -105,6 +105,7 @@ export const getDataAssetsHeaderInfo = (
<> <>
{dashboardDetails.sourceUrl && ( {dashboardDetails.sourceUrl && (
<ExtraInfoLink <ExtraInfoLink
newTab
href={dashboardDetails.sourceUrl} href={dashboardDetails.sourceUrl}
label="" label=""
value={getEntityName(dashboardDetails)} value={getEntityName(dashboardDetails)}
@ -147,6 +148,7 @@ export const getDataAssetsHeaderInfo = (
<> <>
{pipelineDetails.sourceUrl && ( {pipelineDetails.sourceUrl && (
<ExtraInfoLink <ExtraInfoLink
newTab
href={pipelineDetails.sourceUrl} href={pipelineDetails.sourceUrl}
label="" label=""
value={getEntityName(pipelineDetails)} value={getEntityName(pipelineDetails)}
@ -178,6 +180,7 @@ export const getDataAssetsHeaderInfo = (
)} )}
{mlModelDetail.server && ( {mlModelDetail.server && (
<ExtraInfoLink <ExtraInfoLink
newTab
href={mlModelDetail.server} href={mlModelDetail.server}
label={t('label.server')} label={t('label.server')}
value={mlModelDetail.server} value={mlModelDetail.server}
@ -388,6 +391,7 @@ export const getDataAssetsHeaderInfo = (
<> <>
{storedProcedureDetails.sourceUrl && ( {storedProcedureDetails.sourceUrl && (
<ExtraInfoLink <ExtraInfoLink
newTab
href={storedProcedureDetails.sourceUrl} href={storedProcedureDetails.sourceUrl}
label="" label=""
value={getEntityName(storedProcedureDetails)} value={getEntityName(storedProcedureDetails)}
@ -422,6 +426,7 @@ export const getDataAssetsHeaderInfo = (
<> <>
{apiCollection.endpointURL && ( {apiCollection.endpointURL && (
<ExtraInfoLink <ExtraInfoLink
newTab
href={apiCollection.endpointURL} href={apiCollection.endpointURL}
label={t('label.endpoint-url')} label={t('label.endpoint-url')}
value={apiCollection.endpointURL} value={apiCollection.endpointURL}
@ -451,6 +456,7 @@ export const getDataAssetsHeaderInfo = (
)} )}
{apiEndpoint.endpointURL && ( {apiEndpoint.endpointURL && (
<ExtraInfoLink <ExtraInfoLink
newTab
href={apiEndpoint.endpointURL} href={apiEndpoint.endpointURL}
label={t('label.endpoint-url')} label={t('label.endpoint-url')}
value={apiEndpoint.endpointURL} value={apiEndpoint.endpointURL}