mirror of
https://github.com/datahub-project/datahub.git
synced 2025-10-10 16:33:48 +00:00
feat(ui): Display 'View in Github' if externalUrl is link to GitHub (#6253)
This commit is contained in:
parent
f1aeafa462
commit
a28fc1ede8
@ -68,6 +68,7 @@ export const ChartPreview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.Chart, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.Chart, urn)}
|
||||||
name={name || ''}
|
name={name || ''}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
type="Chart"
|
type="Chart"
|
||||||
typeIcon={entityRegistry.getIcon(EntityType.Chart, 14, IconStyleType.ACCENT)}
|
typeIcon={entityRegistry.getIcon(EntityType.Chart, 14, IconStyleType.ACCENT)}
|
||||||
|
@ -67,6 +67,7 @@ export const Preview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.Container, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.Container, urn)}
|
||||||
name={name || ''}
|
name={name || ''}
|
||||||
|
urn={urn}
|
||||||
platform={platformName}
|
platform={platformName}
|
||||||
platformInstanceId={platformInstanceId}
|
platformInstanceId={platformInstanceId}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
|
@ -72,6 +72,7 @@ export const DashboardPreview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.Dashboard, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.Dashboard, urn)}
|
||||||
name={name || ''}
|
name={name || ''}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
type={capitalizeFirstLetterOnly(subtype) || 'Dashboard'}
|
type={capitalizeFirstLetterOnly(subtype) || 'Dashboard'}
|
||||||
typeIcon={entityRegistry.getIcon(EntityType.Dashboard, 14, IconStyleType.ACCENT)}
|
typeIcon={entityRegistry.getIcon(EntityType.Dashboard, 14, IconStyleType.ACCENT)}
|
||||||
|
@ -49,6 +49,7 @@ export const Preview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.DataFlow, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.DataFlow, urn)}
|
||||||
name={name}
|
name={name}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
platformInstanceId={platformInstanceId}
|
platformInstanceId={platformInstanceId}
|
||||||
type="Data Pipeline"
|
type="Data Pipeline"
|
||||||
|
@ -52,6 +52,7 @@ export const Preview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.DataJob, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.DataJob, urn)}
|
||||||
name={name}
|
name={name}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
type="Data Task"
|
type="Data Task"
|
||||||
typeIcon={entityRegistry.getIcon(EntityType.DataJob, 14, IconStyleType.ACCENT)}
|
typeIcon={entityRegistry.getIcon(EntityType.DataJob, 14, IconStyleType.ACCENT)}
|
||||||
|
@ -74,6 +74,7 @@ export const Preview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.Dataset, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.Dataset, urn)}
|
||||||
name={name || ''}
|
name={name || ''}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
type={capitalizeFirstLetterOnly(subtype) || 'Dataset'}
|
type={capitalizeFirstLetterOnly(subtype) || 'Dataset'}
|
||||||
logoUrl={platformLogo || ''}
|
logoUrl={platformLogo || ''}
|
||||||
|
@ -26,6 +26,7 @@ export const Preview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.Domain, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.Domain, urn)}
|
||||||
name={name || ''}
|
name={name || ''}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
type="Domain"
|
type="Domain"
|
||||||
typeIcon={entityRegistry.getIcon(EntityType.Domain, 14, IconStyleType.ACCENT)}
|
typeIcon={entityRegistry.getIcon(EntityType.Domain, 14, IconStyleType.ACCENT)}
|
||||||
|
@ -22,6 +22,7 @@ export const Preview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.GlossaryNode, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.GlossaryNode, urn)}
|
||||||
name={name || ''}
|
name={name || ''}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
owners={owners}
|
owners={owners}
|
||||||
logoComponent={<FolderOutlined style={{ fontSize: '20px' }} />}
|
logoComponent={<FolderOutlined style={{ fontSize: '20px' }} />}
|
||||||
|
@ -28,6 +28,7 @@ export const Preview = ({
|
|||||||
previewType={previewType}
|
previewType={previewType}
|
||||||
url={entityRegistry.getEntityUrl(EntityType.GlossaryTerm, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.GlossaryTerm, urn)}
|
||||||
name={name || ''}
|
name={name || ''}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
owners={owners}
|
owners={owners}
|
||||||
logoComponent={<BookOutlined style={{ fontSize: '20px' }} />}
|
logoComponent={<BookOutlined style={{ fontSize: '20px' }} />}
|
||||||
|
@ -27,6 +27,7 @@ export const Preview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.Mlfeature, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.Mlfeature, urn)}
|
||||||
name={name}
|
name={name}
|
||||||
|
urn={urn}
|
||||||
platformInstanceId={platformInstanceId}
|
platformInstanceId={platformInstanceId}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
platform={capitalizeFirstLetterOnly(platform?.properties?.displayName) || featureNamespace}
|
platform={capitalizeFirstLetterOnly(platform?.properties?.displayName) || featureNamespace}
|
||||||
|
@ -26,6 +26,7 @@ export const Preview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.MlfeatureTable, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.MlfeatureTable, urn)}
|
||||||
name={name}
|
name={name}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
type={entityRegistry.getEntityName(EntityType.MlfeatureTable)}
|
type={entityRegistry.getEntityName(EntityType.MlfeatureTable)}
|
||||||
typeIcon={entityRegistry.getIcon(EntityType.MlfeatureTable, 14, IconStyleType.ACCENT)}
|
typeIcon={entityRegistry.getIcon(EntityType.MlfeatureTable, 14, IconStyleType.ACCENT)}
|
||||||
|
@ -13,6 +13,7 @@ export const Preview = ({ model }: { model: MlModel }): JSX.Element => {
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.Mlmodel, model.urn)}
|
url={entityRegistry.getEntityUrl(EntityType.Mlmodel, model.urn)}
|
||||||
name={model.name || ''}
|
name={model.name || ''}
|
||||||
|
urn={model.urn}
|
||||||
description={model.description || ''}
|
description={model.description || ''}
|
||||||
platformInstanceId={model.dataPlatformInstance?.instanceId}
|
platformInstanceId={model.dataPlatformInstance?.instanceId}
|
||||||
type={entityRegistry.getEntityName(EntityType.Mlmodel)}
|
type={entityRegistry.getEntityName(EntityType.Mlmodel)}
|
||||||
|
@ -12,6 +12,7 @@ export const Preview = ({ group }: { group: MlModelGroup }): JSX.Element => {
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.MlmodelGroup, group.urn)}
|
url={entityRegistry.getEntityUrl(EntityType.MlmodelGroup, group.urn)}
|
||||||
name={group?.name || ''}
|
name={group?.name || ''}
|
||||||
|
urn={group.urn}
|
||||||
platformInstanceId={group.dataPlatformInstance?.instanceId}
|
platformInstanceId={group.dataPlatformInstance?.instanceId}
|
||||||
description={group?.description || ''}
|
description={group?.description || ''}
|
||||||
type="MLModel Group"
|
type="MLModel Group"
|
||||||
|
@ -27,6 +27,7 @@ export const Preview = ({
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.MlprimaryKey, urn)}
|
url={entityRegistry.getEntityUrl(EntityType.MlprimaryKey, urn)}
|
||||||
name={name}
|
name={name}
|
||||||
|
urn={urn}
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
platform={capitalizeFirstLetterOnly(platform?.properties?.displayName) || featureNamespace}
|
platform={capitalizeFirstLetterOnly(platform?.properties?.displayName) || featureNamespace}
|
||||||
logoUrl={platform?.properties?.logoUrl || ''}
|
logoUrl={platform?.properties?.logoUrl || ''}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
import { ArrowRightOutlined } from '@ant-design/icons';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components/macro';
|
||||||
|
import { EntityType } from '../../../types.generated';
|
||||||
|
import analytics, { EventType, EntityActionType } from '../../analytics';
|
||||||
|
|
||||||
|
const GITHUB_LINK = 'github.com';
|
||||||
|
const GITHUB = 'GitHub';
|
||||||
|
|
||||||
|
const ExternalUrlWrapper = styled.span`
|
||||||
|
font-size: 12px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledButton = styled(Button)`
|
||||||
|
> :hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
&&& {
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
padding-left: 12px;
|
||||||
|
padding-right: 12px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
externalUrl: string;
|
||||||
|
platformName?: string;
|
||||||
|
entityUrn: string;
|
||||||
|
entityType?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ExternalUrlButton({ externalUrl, platformName, entityType, entityUrn }: Props) {
|
||||||
|
function sendAnalytics() {
|
||||||
|
analytics.event({
|
||||||
|
type: EventType.EntityActionEvent,
|
||||||
|
actionType: EntityActionType.ClickExternalUrl,
|
||||||
|
entityType: entityType as EntityType,
|
||||||
|
entityUrn,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let displayedName = platformName;
|
||||||
|
if (externalUrl.toLocaleLowerCase().includes(GITHUB_LINK)) {
|
||||||
|
displayedName = GITHUB;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ExternalUrlWrapper>
|
||||||
|
<StyledButton
|
||||||
|
type="link"
|
||||||
|
href={externalUrl}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
onClick={sendAnalytics}
|
||||||
|
>
|
||||||
|
View in {displayedName} <ArrowRightOutlined style={{ fontSize: 12 }} />
|
||||||
|
</StyledButton>
|
||||||
|
</ExternalUrlWrapper>
|
||||||
|
);
|
||||||
|
}
|
@ -1,10 +1,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { ArrowRightOutlined } from '@ant-design/icons';
|
|
||||||
import { Button } from 'antd';
|
|
||||||
import styled from 'styled-components/macro';
|
import styled from 'styled-components/macro';
|
||||||
import { capitalizeFirstLetterOnly } from '../../../../../shared/textUtil';
|
import { capitalizeFirstLetterOnly } from '../../../../../shared/textUtil';
|
||||||
import { useEntityData, useRefetch } from '../../../EntityContext';
|
import { useEntityData, useRefetch } from '../../../EntityContext';
|
||||||
import analytics, { EventType, EntityActionType } from '../../../../../analytics';
|
|
||||||
import { EntityHealthStatus } from './EntityHealthStatus';
|
import { EntityHealthStatus } from './EntityHealthStatus';
|
||||||
import EntityDropdown, { EntityMenuItems } from '../../../EntityDropdown/EntityDropdown';
|
import EntityDropdown, { EntityMenuItems } from '../../../EntityDropdown/EntityDropdown';
|
||||||
import PlatformContent from './PlatformContent';
|
import PlatformContent from './PlatformContent';
|
||||||
@ -18,6 +15,7 @@ import { DeprecationPill } from '../../../components/styled/DeprecationPill';
|
|||||||
import CompactContext from '../../../../../shared/CompactContext';
|
import CompactContext from '../../../../../shared/CompactContext';
|
||||||
import { EntitySubHeaderSection } from '../../../types';
|
import { EntitySubHeaderSection } from '../../../types';
|
||||||
import EntityActions, { EntityActionItem } from '../../../entity/EntityActions';
|
import EntityActions, { EntityActionItem } from '../../../entity/EntityActions';
|
||||||
|
import ExternalUrlButton from '../../../ExternalUrlButton';
|
||||||
|
|
||||||
const TitleWrapper = styled.div`
|
const TitleWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -57,18 +55,6 @@ const TopButtonsWrapper = styled.div`
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ExternalUrlContainer = styled.span`
|
|
||||||
font-size: 14px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const ExternalUrlButton = styled(Button)`
|
|
||||||
> :hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
padding-left: 12px;
|
|
||||||
padding-right: 12px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export function getCanEditName(entityType: EntityType, privileges?: PlatformPrivileges) {
|
export function getCanEditName(entityType: EntityType, privileges?: PlatformPrivileges) {
|
||||||
switch (entityType) {
|
switch (entityType) {
|
||||||
case EntityType.GlossaryTerm:
|
case EntityType.GlossaryTerm:
|
||||||
@ -106,15 +92,6 @@ export const EntityHeader = ({
|
|||||||
const entityCount = entityData?.entityCount;
|
const entityCount = entityData?.entityCount;
|
||||||
const isCompact = React.useContext(CompactContext);
|
const isCompact = React.useContext(CompactContext);
|
||||||
|
|
||||||
const sendAnalytics = () => {
|
|
||||||
analytics.event({
|
|
||||||
type: EventType.EntityActionEvent,
|
|
||||||
actionType: EntityActionType.ClickExternalUrl,
|
|
||||||
entityType,
|
|
||||||
entityUrn: urn,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const canEditName = isNameEditable && getCanEditName(entityType, me?.platformPrivileges as PlatformPrivileges);
|
const canEditName = isNameEditable && getCanEditName(entityType, me?.platformPrivileges as PlatformPrivileges);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -146,16 +123,12 @@ export const EntityHeader = ({
|
|||||||
<SideHeaderContent>
|
<SideHeaderContent>
|
||||||
<TopButtonsWrapper>
|
<TopButtonsWrapper>
|
||||||
{externalUrl && (
|
{externalUrl && (
|
||||||
<ExternalUrlContainer>
|
<ExternalUrlButton
|
||||||
<ExternalUrlButton
|
externalUrl={externalUrl}
|
||||||
type="link"
|
entityUrn={urn}
|
||||||
href={externalUrl}
|
platformName={platformName}
|
||||||
target="_blank"
|
entityType={entityType}
|
||||||
onClick={sendAnalytics}
|
/>
|
||||||
>
|
|
||||||
View in {platformName} <ArrowRightOutlined style={{ fontSize: 12 }} />
|
|
||||||
</ExternalUrlButton>
|
|
||||||
</ExternalUrlContainer>
|
|
||||||
)}
|
)}
|
||||||
{headerActionItems && (
|
{headerActionItems && (
|
||||||
<EntityActions urn={urn} actionItems={headerActionItems} refetchForEntity={refetch} />
|
<EntityActions urn={urn} actionItems={headerActionItems} refetchForEntity={refetch} />
|
||||||
|
@ -57,6 +57,7 @@ export class TagEntity implements Entity<Tag> {
|
|||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
description={data.description || ''}
|
description={data.description || ''}
|
||||||
name={data.name}
|
name={data.name}
|
||||||
|
urn={data.urn}
|
||||||
url={`/${this.getPathName()}/${urlEncodeUrn(data.urn)}`}
|
url={`/${this.getPathName()}/${urlEncodeUrn(data.urn)}`}
|
||||||
logoComponent={<PreviewTagIcon />}
|
logoComponent={<PreviewTagIcon />}
|
||||||
type="Tag"
|
type="Tag"
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import React, { ReactNode, useState } from 'react';
|
import React, { ReactNode, useState } from 'react';
|
||||||
import { Button, Divider, Tooltip, Typography } from 'antd';
|
import { Divider, Tooltip, Typography } from 'antd';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { ArrowRightOutlined } from '@ant-design/icons';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
GlobalTags,
|
GlobalTags,
|
||||||
@ -28,6 +27,7 @@ import EntityCount from '../entity/shared/containers/profile/header/EntityCount'
|
|||||||
import { ExpandedActorGroup } from '../entity/shared/components/styled/ExpandedActorGroup';
|
import { ExpandedActorGroup } from '../entity/shared/components/styled/ExpandedActorGroup';
|
||||||
import { DeprecationPill } from '../entity/shared/components/styled/DeprecationPill';
|
import { DeprecationPill } from '../entity/shared/components/styled/DeprecationPill';
|
||||||
import { PreviewType } from '../entity/Entity';
|
import { PreviewType } from '../entity/Entity';
|
||||||
|
import ExternalUrlButton from '../entity/shared/ExternalUrlButton';
|
||||||
|
|
||||||
const PreviewContainer = styled.div`
|
const PreviewContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -129,21 +129,6 @@ const InsightIconContainer = styled.span`
|
|||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ExternalUrlContainer = styled.span`
|
|
||||||
font-size: 12px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const ExternalUrlButton = styled(Button)`
|
|
||||||
> :hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
&&& {
|
|
||||||
padding-bottom: 0px;
|
|
||||||
}
|
|
||||||
padding-left: 12px;
|
|
||||||
padding-right: 12px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const UserListContainer = styled.div`
|
const UserListContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -164,6 +149,7 @@ const UserListTitle = styled(Typography.Text)`
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
name: string;
|
name: string;
|
||||||
|
urn: string;
|
||||||
logoUrl?: string;
|
logoUrl?: string;
|
||||||
logoComponent?: JSX.Element;
|
logoComponent?: JSX.Element;
|
||||||
url: string;
|
url: string;
|
||||||
@ -200,6 +186,7 @@ interface Props {
|
|||||||
|
|
||||||
export default function DefaultPreviewCard({
|
export default function DefaultPreviewCard({
|
||||||
name,
|
name,
|
||||||
|
urn,
|
||||||
logoUrl,
|
logoUrl,
|
||||||
logoComponent,
|
logoComponent,
|
||||||
url,
|
url,
|
||||||
@ -292,11 +279,12 @@ export default function DefaultPreviewCard({
|
|||||||
<DeprecationPill deprecation={deprecation} urn="" showUndeprecate={false} preview />
|
<DeprecationPill deprecation={deprecation} urn="" showUndeprecate={false} preview />
|
||||||
)}
|
)}
|
||||||
{externalUrl && (
|
{externalUrl && (
|
||||||
<ExternalUrlContainer>
|
<ExternalUrlButton
|
||||||
<ExternalUrlButton type="link" href={externalUrl} target="_blank">
|
externalUrl={externalUrl}
|
||||||
View in {platform} <ArrowRightOutlined style={{ fontSize: 12 }} />
|
platformName={platform}
|
||||||
</ExternalUrlButton>
|
entityUrn={urn}
|
||||||
</ExternalUrlContainer>
|
entityType={type}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</EntityTitleContainer>
|
</EntityTitleContainer>
|
||||||
|
|
||||||
|
@ -140,6 +140,7 @@ export const EntityNameList = ({
|
|||||||
)}
|
)}
|
||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
name={displayName}
|
name={displayName}
|
||||||
|
urn={entity.urn}
|
||||||
logoUrl={platformLogoUrl || undefined}
|
logoUrl={platformLogoUrl || undefined}
|
||||||
logoComponent={fallbackIcon}
|
logoComponent={fallbackIcon}
|
||||||
url={url}
|
url={url}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user