From 71ee0aa5c93269b4d997866cea2376ac786351fa Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 14 Sep 2023 17:28:51 -0500 Subject: [PATCH] [ui] Show targeted asset checks in run list, run details header (#16519) ## Summary & Motivation This builds on the GraphQL in #16510. Runs that had an assetCheckSelection now show those asset checks in both the run list and run details page. image image ## How I Tested These Changes We have surprisingly no storybook coverage of these two run components -- I will add some stories in a follow-up once the urgent stuff for tomorrow's release is done! --------- Co-authored-by: bengotow --- .../src/icon-svgs/asset_check.svg | 10 +- .../VirtualizedAssetCheckTable.tsx | 7 +- .../src/assets/assetDetailsPathForKey.tsx | 4 + .../src/instance/backfill/BackfillRow.tsx | 2 +- .../types/InstanceConcurrency.types.ts | 5 + .../src/instance/types/JobMenu.types.ts | 5 + .../types/InstigationTick.types.ts | 5 + .../types/PartitionRunList.types.ts | 5 + .../pipelines/types/PipelineRunsRoot.types.ts | 5 + ...Collection.tsx => AssetTagCollections.tsx} | 129 +++++++++++++++--- .../src/runs/LogsRowStructuredContent.tsx | 11 +- .../ui-core/src/runs/RunFragments.tsx | 6 + .../packages/ui-core/src/runs/RunRoot.tsx | 3 +- .../packages/ui-core/src/runs/RunTable.tsx | 13 +- .../__tests__/AssetKeyTagCollection.test.tsx | 2 +- .../runs/__tests__/RunActionsMenu.test.tsx | 1 + .../types/RunActionButtonsTestQuery.types.ts | 5 + .../src/runs/types/RunFragments.types.ts | 10 ++ .../ui-core/src/runs/types/RunRoot.types.ts | 5 + .../ui-core/src/runs/types/RunTable.types.ts | 5 + .../ui-core/src/runs/types/RunsRoot.types.ts | 5 + .../src/schedules/types/ScheduleRoot.types.ts | 5 + .../sensors/types/SensorPreviousRuns.types.ts | 5 + 23 files changed, 215 insertions(+), 38 deletions(-) rename js_modules/dagster-ui/packages/ui-core/src/runs/{AssetKeyTagCollection.tsx => AssetTagCollections.tsx} (51%) diff --git a/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/asset_check.svg b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/asset_check.svg index 76db2d83c249a..36deadc30d75a 100644 --- a/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/asset_check.svg +++ b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/asset_check.svg @@ -1,4 +1,8 @@ - - - + + + \ No newline at end of file diff --git a/js_modules/dagster-ui/packages/ui-core/src/assets/asset-checks/VirtualizedAssetCheckTable.tsx b/js_modules/dagster-ui/packages/ui-core/src/assets/asset-checks/VirtualizedAssetCheckTable.tsx index cdbd741c00f48..6a834539492ae 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/assets/asset-checks/VirtualizedAssetCheckTable.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/assets/asset-checks/VirtualizedAssetCheckTable.tsx @@ -7,7 +7,7 @@ import styled from 'styled-components'; import {TimestampDisplay} from '../../schedules/TimestampDisplay'; import {testId} from '../../testing/testId'; import {HeaderCell, Row, RowCell, Container, Inner} from '../../ui/VirtualizedTable'; -import {assetDetailsPathForKey} from '../assetDetailsPathForKey'; +import {assetDetailsPathForAssetCheck} from '../assetDetailsPathForKey'; import {MetadataCell} from './AssetCheckDetailModal'; import {AssetCheckStatusTag} from './AssetCheckStatusTag'; @@ -80,10 +80,7 @@ export const VirtualizedAssetCheckRow = ({assetNode, height, start, row}: AssetC {row.name} diff --git a/js_modules/dagster-ui/packages/ui-core/src/assets/assetDetailsPathForKey.tsx b/js_modules/dagster-ui/packages/ui-core/src/assets/assetDetailsPathForKey.tsx index 38e51fa9423e9..eea552062a41b 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/assets/assetDetailsPathForKey.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/assets/assetDetailsPathForKey.tsx @@ -5,3 +5,7 @@ import {AssetKey, AssetViewParams} from './types'; export const assetDetailsPathForKey = (key: AssetKey, query?: AssetViewParams) => { return `/assets/${key.path.map(encodeURIComponent).join('/')}?${qs.stringify(query)}`; }; + +export const assetDetailsPathForAssetCheck = (check: {assetKey: AssetKey; name: string}) => { + return assetDetailsPathForKey(check.assetKey, {view: 'checks', checkDetail: check.name}); +}; diff --git a/js_modules/dagster-ui/packages/ui-core/src/instance/backfill/BackfillRow.tsx b/js_modules/dagster-ui/packages/ui-core/src/instance/backfill/BackfillRow.tsx index 786299398abb8..ad17356938b74 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/instance/backfill/BackfillRow.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/instance/backfill/BackfillRow.tsx @@ -12,7 +12,7 @@ import {isHiddenAssetGroupJob} from '../../asset-graph/Utils'; import {BulkActionStatus, RunStatus} from '../../graphql/types'; import {PartitionStatus, PartitionStatusHealthSourceOps} from '../../partitions/PartitionStatus'; import {PipelineReference} from '../../pipelines/PipelineReference'; -import {AssetKeyTagCollection} from '../../runs/AssetKeyTagCollection'; +import {AssetKeyTagCollection} from '../../runs/AssetTagCollections'; import {inProgressStatuses} from '../../runs/RunStatuses'; import {RunStatusTagsWithCounts} from '../../runs/RunTimeline'; import {runsPathWithFilters} from '../../runs/RunsFilterInput'; diff --git a/js_modules/dagster-ui/packages/ui-core/src/instance/types/InstanceConcurrency.types.ts b/js_modules/dagster-ui/packages/ui-core/src/instance/types/InstanceConcurrency.types.ts index 7401f9ee40afa..607a8de037ca6 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/instance/types/InstanceConcurrency.types.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/instance/types/InstanceConcurrency.types.ts @@ -91,6 +91,11 @@ export type RunsForConcurrencyKeyQuery = { repositoryLocationName: string; } | null; assetSelection: Array<{__typename: 'AssetKey'; path: Array}> | null; + assetCheckSelection: Array<{ + __typename: 'AssetCheckhandle'; + name: string; + assetKey: {__typename: 'AssetKey'; path: Array}; + }> | null; tags: Array<{__typename: 'PipelineTag'; key: string; value: string}>; }>; }; diff --git a/js_modules/dagster-ui/packages/ui-core/src/instance/types/JobMenu.types.ts b/js_modules/dagster-ui/packages/ui-core/src/instance/types/JobMenu.types.ts index 99745164e9189..84ce2d0fff53c 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/instance/types/JobMenu.types.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/instance/types/JobMenu.types.ts @@ -44,6 +44,11 @@ export type RunReExecutionQuery = { key: {__typename: 'AssetKey'; path: Array}; }>; assetSelection: Array<{__typename: 'AssetKey'; path: Array}> | null; + assetCheckSelection: Array<{ + __typename: 'AssetCheckhandle'; + name: string; + assetKey: {__typename: 'AssetKey'; path: Array}; + }> | null; executionPlan: { __typename: 'ExecutionPlan'; artifactsPersisted: boolean; diff --git a/js_modules/dagster-ui/packages/ui-core/src/instigation/types/InstigationTick.types.ts b/js_modules/dagster-ui/packages/ui-core/src/instigation/types/InstigationTick.types.ts index 20cb3e5684379..17a30da92978f 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/instigation/types/InstigationTick.types.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/instigation/types/InstigationTick.types.ts @@ -67,6 +67,11 @@ export type LaunchedRunListQuery = { repositoryLocationName: string; } | null; assetSelection: Array<{__typename: 'AssetKey'; path: Array}> | null; + assetCheckSelection: Array<{ + __typename: 'AssetCheckhandle'; + name: string; + assetKey: {__typename: 'AssetKey'; path: Array}; + }> | null; tags: Array<{__typename: 'PipelineTag'; key: string; value: string}>; }>; }; diff --git a/js_modules/dagster-ui/packages/ui-core/src/partitions/types/PartitionRunList.types.ts b/js_modules/dagster-ui/packages/ui-core/src/partitions/types/PartitionRunList.types.ts index f68d833c29c00..4aef4b820de8e 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/partitions/types/PartitionRunList.types.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/partitions/types/PartitionRunList.types.ts @@ -47,6 +47,11 @@ export type PartitionRunListQuery = { repositoryLocationName: string; } | null; assetSelection: Array<{__typename: 'AssetKey'; path: Array}> | null; + assetCheckSelection: Array<{ + __typename: 'AssetCheckhandle'; + name: string; + assetKey: {__typename: 'AssetKey'; path: Array}; + }> | null; tags: Array<{__typename: 'PipelineTag'; key: string; value: string}>; }>; }; diff --git a/js_modules/dagster-ui/packages/ui-core/src/pipelines/types/PipelineRunsRoot.types.ts b/js_modules/dagster-ui/packages/ui-core/src/pipelines/types/PipelineRunsRoot.types.ts index 4a4916babe4f3..7e03e74cb0363 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/pipelines/types/PipelineRunsRoot.types.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/pipelines/types/PipelineRunsRoot.types.ts @@ -49,6 +49,11 @@ export type PipelineRunsRootQuery = { repositoryLocationName: string; } | null; assetSelection: Array<{__typename: 'AssetKey'; path: Array}> | null; + assetCheckSelection: Array<{ + __typename: 'AssetCheckhandle'; + name: string; + assetKey: {__typename: 'AssetKey'; path: Array}; + }> | null; tags: Array<{__typename: 'PipelineTag'; key: string; value: string}>; }>; }; diff --git a/js_modules/dagster-ui/packages/ui-core/src/runs/AssetKeyTagCollection.tsx b/js_modules/dagster-ui/packages/ui-core/src/runs/AssetTagCollections.tsx similarity index 51% rename from js_modules/dagster-ui/packages/ui-core/src/runs/AssetKeyTagCollection.tsx rename to js_modules/dagster-ui/packages/ui-core/src/runs/AssetTagCollections.tsx index aba2f3f559bf5..5d08d96b95ae1 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/runs/AssetKeyTagCollection.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/runs/AssetTagCollections.tsx @@ -12,25 +12,36 @@ import * as React from 'react'; import {Link} from 'react-router-dom'; import {displayNameForAssetKey} from '../asset-graph/Utils'; -import {assetDetailsPathForKey} from '../assets/assetDetailsPathForKey'; +import { + assetDetailsPathForAssetCheck, + assetDetailsPathForKey, +} from '../assets/assetDetailsPathForKey'; import {globalAssetGraphPathForAssetsAndDescendants} from '../assets/globalAssetGraphPathToString'; import {AssetKey} from '../assets/types'; import {TagActionsPopover} from '../ui/TagActions'; import {VirtualizedItemListForDialog} from '../ui/VirtualizedItemListForDialog'; -export const AssetKeyTagCollection: React.FC<{ - assetKeys: AssetKey[] | null; - modalTitle?: string; - useTags?: boolean; -}> = React.memo(({assetKeys, useTags, modalTitle = 'Assets in Run'}) => { - const [showMore, setShowMore] = React.useState(false); +const renderItemAssetKey = (assetKey: AssetKey) => ( + {displayNameForAssetKey(assetKey)} +); - if (!assetKeys || !assetKeys.length) { - return null; - } +const renderItemAssetCheck = (assetCheck: Check) => ( + {labelForAssetCheck(assetCheck)} +); + +const labelForAssetCheck = (check: Check) => { + return `${check.name} on ${displayNameForAssetKey(check.assetKey)}`; +}; - const showMoreDialog = - assetKeys.length > 1 ? ( +function useShowMoreDialog( + modalTitle: string, + items: T[] | null, + renderItem: (item: T) => React.ReactNode, +) { + const [showMore, setShowMore] = React.useState(false); + + const dialog = + !!items && items.length > 1 ? ( setShowMore(false)} @@ -38,12 +49,7 @@ export const AssetKeyTagCollection: React.FC<{ isOpen={showMore} >
- ( - {displayNameForAssetKey(assetKey)} - )} - /> +