From 55d842522211233c6164414c941557ac27f9a640 Mon Sep 17 00:00:00 2001 From: Ben Pankow Date: Thu, 6 Jun 2024 11:30:53 -0700 Subject: [PATCH] [ui] update code link rendering (#22323) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Updates code link rendering to match new designs. Also adds rendering in the asset sidebar. Screenshot 2024-06-06 at 8 53 14 AM Screenshot 2024-06-06 at 8 53 08 AM Screenshot 2024-06-06 at 8 53 05 AM ## Test Plan Tested locally. --- .../ui-components/src/components/Icon.tsx | 2 + .../src/icon-svgs/code_block.svg | 3 + .../ui-core/src/assets/AssetNodeOverview.tsx | 15 ++- .../packages/ui-core/src/assets/AssetView.tsx | 13 --- .../ui-core/src/code-links/CodeLink.tsx | 98 ++++++------------- .../ui-core/src/metadata/MetadataEntry.tsx | 35 ++++++- 6 files changed, 83 insertions(+), 83 deletions(-) create mode 100644 js_modules/dagster-ui/packages/ui-components/src/icon-svgs/code_block.svg diff --git a/js_modules/dagster-ui/packages/ui-components/src/components/Icon.tsx b/js_modules/dagster-ui/packages/ui-components/src/components/Icon.tsx index 267257f4f85f3..2b87f99bcec23 100644 --- a/js_modules/dagster-ui/packages/ui-components/src/components/Icon.tsx +++ b/js_modules/dagster-ui/packages/ui-components/src/components/Icon.tsx @@ -40,6 +40,7 @@ import checklist from '../icon-svgs/checklist.svg'; import chevron_left from '../icon-svgs/chevron_left.svg'; import chevron_right from '../icon-svgs/chevron_right.svg'; import close from '../icon-svgs/close.svg'; +import code_block from '../icon-svgs/code_block.svg'; import code_location from '../icon-svgs/code_location.svg'; import collapse_arrows from '../icon-svgs/collapse_arrows.svg'; import column_lineage from '../icon-svgs/column_lineage.svg'; @@ -292,6 +293,7 @@ export const Icons = { chevron_right, chevron_left, close, + code_block, code_location, compute_kind, console: console_icon, diff --git a/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/code_block.svg b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/code_block.svg new file mode 100644 index 0000000000000..e711a43c95e8a --- /dev/null +++ b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/code_block.svg @@ -0,0 +1,3 @@ + + + diff --git a/js_modules/dagster-ui/packages/ui-core/src/assets/AssetNodeOverview.tsx b/js_modules/dagster-ui/packages/ui-core/src/assets/AssetNodeOverview.tsx index 9e3a7f702a5a6..4d83add5349ee 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/assets/AssetNodeOverview.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/assets/AssetNodeOverview.tsx @@ -53,18 +53,20 @@ import { } from '../asset-graph/Utils'; import {StatusDot} from '../asset-graph/sidebar/StatusDot'; import {AssetNodeForGraphQueryFragment} from '../asset-graph/types/useAssetGraphData.types'; +import {CodeLink, getCodeReferenceKey} from '../code-links/CodeLink'; import {DagsterTypeSummary} from '../dagstertype/DagsterType'; import { AssetComputeKindTag, AssetStorageKindTag, isCanonicalStorageKindTag, } from '../graph/KindTags'; -import {IntMetadataEntry} from '../graphql/types'; +import {CodeReferencesMetadataEntry, IntMetadataEntry} from '../graphql/types'; import {useLaunchPadHooks} from '../launchpad/LaunchpadHooksContext'; import {isCanonicalRowCountMetadataEntry} from '../metadata/MetadataEntry'; import { TableSchema, TableSchemaAssetContext, + isCanonicalCodeSourceEntry, isCanonicalRelationIdentifierEntry, isCanonicalUriEntry, } from '../metadata/TableSchema'; @@ -235,6 +237,10 @@ export const AssetNodeOverview = ({ ); const uriMetadata = assetNode.metadataEntries?.find(isCanonicalUriEntry); + const codeSource = assetNode.metadataEntries?.find((m) => isCanonicalCodeSourceEntry(m)) as + | CodeReferencesMetadataEntry + | undefined; + const renderDefinitionSection = () => ( @@ -321,6 +327,13 @@ export const AssetNodeOverview = ({ filteredTags.length > 0 && filteredTags.map((tag, idx) => {buildTagString(tag)})} + + {codeSource && + codeSource.codeReferences && + codeSource.codeReferences.map((ref) => ( + + ))} + ); diff --git a/js_modules/dagster-ui/packages/ui-core/src/assets/AssetView.tsx b/js_modules/dagster-ui/packages/ui-core/src/assets/AssetView.tsx index f57f703fdd435..d548bcdaaf588 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/assets/AssetView.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/assets/AssetView.tsx @@ -8,7 +8,6 @@ import {useSetRecoilState} from 'recoil'; import {AssetEvents} from './AssetEvents'; import {AssetFeatureContext} from './AssetFeatureContext'; -import {metadataForAssetNode} from './AssetMetadata'; import {ASSET_NODE_DEFINITION_FRAGMENT, AssetNodeDefinition} from './AssetNodeDefinition'; import {ASSET_NODE_INSTIGATORS_FRAGMENT} from './AssetNodeInstigatorTag'; import {AssetNodeLineage} from './AssetNodeLineage'; @@ -48,10 +47,7 @@ import { } from '../asset-graph/Utils'; import {useAssetGraphData} from '../asset-graph/useAssetGraphData'; import {StaleReasonsTag} from '../assets/Stale'; -import {CodeLink} from '../code-links/CodeLink'; -import {CodeReferencesMetadataEntry} from '../graphql/types'; import {useQueryPersistedState} from '../hooks/useQueryPersistedState'; -import {isCanonicalCodeSourceEntry} from '../metadata/TableSchema'; import {PageLoadTrace} from '../performance'; import {useBlockTraceOnQueryResult} from '../performance/TraceContext'; @@ -275,12 +271,6 @@ export const AssetView = ({assetKey, trace, headerBreadcrumbs}: Props) => { refresh, ); - const assetMetadata = definition && metadataForAssetNode(definition).assetMetadata; - const codeSource = assetMetadata?.find((m) => isCanonicalCodeSourceEntry(m)) as - | CodeReferencesMetadataEntry - | undefined; - console.log(codeSource); - return ( { } right={ - {codeSource && codeSource.codeReferences && codeSource.codeReferences.length > 0 && ( - - )} {definition && definition.isObservable ? ( { switch (codeReference.__typename) { case 'LocalFileCodeReference': - return 'open_in_new'; + return 'code_block'; case 'UrlCodeReference': return codeReference.url.includes('github') ? 'github' : 'gitlab'; default: @@ -64,7 +56,7 @@ const getCodeReferenceLink = ( } }; -const getCodeReferenceKey = (codeReference: SourceLocation): string => { +export const getCodeReferenceKey = (codeReference: SourceLocation): string => { switch (codeReference.__typename) { case 'LocalFileCodeReference': return `${codeReference.filePath}:${codeReference.lineNumber}`; @@ -75,63 +67,37 @@ const getCodeReferenceKey = (codeReference: SourceLocation): string => { } }; -export const CodeLink = ({codeLinkData}: {codeLinkData: CodeReferencesMetadataEntry}) => { - const [codeLinkProtocol, _] = React.useContext(CodeLinkProtocolContext); - - const sources = codeLinkData.codeReferences; +export const getCodeReferenceTooltip = (codeReference: SourceLocation): string => { + switch (codeReference.__typename) { + case 'LocalFileCodeReference': + return `Open in editor`; + case 'UrlCodeReference': + if (codeReference.url.includes('github')) { + return `Open in GitHub`; + } else { + return `Open in GitLab`; + } + default: + assertUnreachable(codeReference); + } +}; - const hasMultipleCodeSources = sources.length > 1; - const firstSource = sources[0] as SourceLocation; +export const CodeLink = ({sourceLocation}: {sourceLocation: SourceLocation}) => { + const [codeLinkProtocol, _] = React.useContext(CodeLinkProtocolContext); return ( - - {hasMultipleCodeSources ? ( - - {sources.map((source) => ( - - {getCodeReferenceLink(codeLinkProtocol, source)} - - } - position="bottom" - display="block" - > - } - style={{maxWidth: 300}} - /> - - ))} - - } - > - - - ) : ( - - {getCodeReferenceLink(codeLinkProtocol, firstSource)} - - } - position="bottom" + + + + - } - href={getCodeReferenceLink(codeLinkProtocol, firstSource)} - style={{maxWidth: 300}} - > - {getCodeReferenceEntryLabel(firstSource)} - - - )} - + {getCodeReferenceEntryLabel(sourceLocation)} + + + + ); }; diff --git a/js_modules/dagster-ui/packages/ui-core/src/metadata/MetadataEntry.tsx b/js_modules/dagster-ui/packages/ui-core/src/metadata/MetadataEntry.tsx index 7d29a6cdcad0c..6a3aa10337e5a 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/metadata/MetadataEntry.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/metadata/MetadataEntry.tsx @@ -23,6 +23,7 @@ import {copyValue} from '../app/DomUtils'; import {assertUnreachable} from '../app/Util'; import {displayNameForAssetKey} from '../asset-graph/Utils'; import {assetDetailsPathForKey} from '../assets/assetDetailsPathForKey'; +import {CodeLink, getCodeReferenceKey} from '../code-links/CodeLink'; import {IntMetadataEntry, MaterializationEvent, TableMetadataEntry} from '../graphql/types'; import {TimestampDisplay} from '../schedules/TimestampDisplay'; import {Markdown} from '../ui/Markdown'; @@ -267,7 +268,27 @@ export const MetadataEntry = ({ ); case 'CodeReferencesMetadataEntry': - return <>; + return ( + ( + + {entry.codeReferences && + entry.codeReferences.map((ref) => ( + + ))} + + )} + > + [Show Code References] + + ); default: return assertUnreachable(entry); } @@ -312,7 +333,7 @@ const MetadataEntryModalAction = (props: { label: string; modalWidth?: number; content: () => React.ReactNode; - copyContent: () => string; + copyContent?: () => string; }) => { const [open, setOpen] = React.useState(false); return ( @@ -327,7 +348,15 @@ const MetadataEntryModalAction = (props: { > {props.content()} - + {props.copyContent && ( + + )}