From 3d206d5a9ab5d685fca41d201cda2fcffe336204 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Wed, 3 Apr 2024 11:38:31 -0500 Subject: [PATCH] =?UTF-8?q?[ui]=20Include=20assets=20with=20failed/missing?= =?UTF-8?q?=20partitions=20in=20=E2=80=9CMaterialize=20unsynced"=20(#20985?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #20463 ## Summary & Motivation This PR updates the behavior of "Materialize unsynced". In addition to assets with the staleStatus = MISSING, we now include assets with missing or failed partitions. I also adjusted the types a bit in these code paths -- because `staleCauses` can be undefined in the types passed to `isAssetStale`, you could technically call it with "include=self" and never get anything but false, which felt a little scary. I broke the function apart into two with stricter types. ## How I Tested These Changes Tested with a graph that includes some partially materialized partitioned assets! --------- Co-authored-by: bengotow --- .../ui-core/src/asset-graph/AssetNode.tsx | 4 +- .../src/asset-graph/CollapsedGroupNode.tsx | 12 ++--- .../src/assets/AssetPartitionDetail.tsx | 5 +- ...Dialog.tsx => CalculateUnsyncedDialog.tsx} | 36 +++++++------ .../src/assets/LaunchAssetExecutionButton.tsx | 12 ++--- .../packages/ui-core/src/assets/Stale.tsx | 54 +++++++++++++------ ...es.ts => CalculateUnsyncedDialog.types.ts} | 7 +++ 7 files changed, 84 insertions(+), 46 deletions(-) rename js_modules/dagster-ui/packages/ui-core/src/assets/{CalculateChangedAndMissingDialog.tsx => CalculateUnsyncedDialog.tsx} (88%) rename js_modules/dagster-ui/packages/ui-core/src/assets/types/{CalculateChangedAndMissingDialog.types.ts => CalculateUnsyncedDialog.types.ts} (71%) diff --git a/js_modules/dagster-ui/packages/ui-core/src/asset-graph/AssetNode.tsx b/js_modules/dagster-ui/packages/ui-core/src/asset-graph/AssetNode.tsx index 72f356b602588..847f16b00880c 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/asset-graph/AssetNode.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/asset-graph/AssetNode.tsx @@ -15,7 +15,7 @@ import {withMiddleTruncation} from '../app/Util'; import {useAssetLiveData} from '../asset-data/AssetLiveDataProvider'; import {PartitionCountTags} from '../assets/AssetNodePartitionCounts'; import {ChangedReasonsTag, MinimalNodeChangedDot} from '../assets/ChangedReasons'; -import {MinimalNodeStaleDot, StaleReasonsTag, isAssetStale} from '../assets/Stale'; +import {MinimalNodeStaleDot, StaleReasonsTag, isAssetStaleFiltered} from '../assets/Stale'; import {AssetChecksStatusSummary} from '../assets/asset-checks/AssetChecksStatusSummary'; import {assetDetailsPathForKey} from '../assets/assetDetailsPathForKey'; import {AssetComputeKindTag} from '../graph/OpTags'; @@ -185,7 +185,7 @@ export const AssetNodeMinimal = ({ const displayName = assetKey.path[assetKey.path.length - 1]!; const isChanged = definition.changedReasons.length; - const isStale = isAssetStale(assetKey, liveData, 'upstream'); + const isStale = isAssetStaleFiltered(assetKey, liveData, 'upstream'); const queuedRuns = liveData?.unstartedRunIds.length; const inProgressRuns = liveData?.inProgressRunIds.length; diff --git a/js_modules/dagster-ui/packages/ui-core/src/asset-graph/CollapsedGroupNode.tsx b/js_modules/dagster-ui/packages/ui-core/src/asset-graph/CollapsedGroupNode.tsx index 606fec8df18b4..76bb6b8588e00 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/asset-graph/CollapsedGroupNode.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/asset-graph/CollapsedGroupNode.tsx @@ -21,7 +21,7 @@ import {groupAssetsByStatus} from './util'; import {CloudOSSContext} from '../app/CloudOSSContext'; import {withMiddleTruncation} from '../app/Util'; import {useAssetsLiveData} from '../asset-data/AssetLiveDataProvider'; -import {CalculateChangedAndMissingDialog} from '../assets/CalculateChangedAndMissingDialog'; +import {CalculateUnsyncedDialog} from '../assets/CalculateUnsyncedDialog'; import {useMaterializationAction} from '../assets/LaunchAssetExecutionButton'; import {AssetKey} from '../assets/types'; import {numberFormatter} from '../ui/formatters'; @@ -205,7 +205,7 @@ export const useGroupNodeContextMenu = ({ preferredJobName?: string; }) => { const {onClick, launchpadElement} = useMaterializationAction(preferredJobName); - const [showCalculatingChangedAndMissingDialog, setShowCalculatingChangedAndMissingDialog] = + const [showCalculatingUnsyncedDialog, setShowCalculatingUnsyncedDialog] = React.useState(false); const { @@ -229,7 +229,7 @@ export const useGroupNodeContextMenu = ({ setShowCalculatingChangedAndMissingDialog(true)} + onClick={() => setShowCalculatingUnsyncedDialog(true)} /> ) : null} @@ -240,10 +240,10 @@ export const useGroupNodeContextMenu = ({ ); const dialog = (
- { - setShowCalculatingChangedAndMissingDialog(false); + setShowCalculatingUnsyncedDialog(false); }} assets={assets} onMaterializeAssets={(assets: AssetKey[], e: React.MouseEvent) => { diff --git a/js_modules/dagster-ui/packages/ui-core/src/assets/AssetPartitionDetail.tsx b/js_modules/dagster-ui/packages/ui-core/src/assets/AssetPartitionDetail.tsx index 34f645226bfc6..d877bcadfa6de 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/assets/AssetPartitionDetail.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/assets/AssetPartitionDetail.tsx @@ -252,7 +252,10 @@ export const AssetPartitionDetail = ({ ) : ( - + )} diff --git a/js_modules/dagster-ui/packages/ui-core/src/assets/CalculateChangedAndMissingDialog.tsx b/js_modules/dagster-ui/packages/ui-core/src/assets/CalculateUnsyncedDialog.tsx similarity index 88% rename from js_modules/dagster-ui/packages/ui-core/src/assets/CalculateChangedAndMissingDialog.tsx rename to js_modules/dagster-ui/packages/ui-core/src/assets/CalculateUnsyncedDialog.tsx index ad780d2c1fd2e..fa5e38428281d 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/assets/CalculateChangedAndMissingDialog.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/assets/CalculateUnsyncedDialog.tsx @@ -16,19 +16,19 @@ import * as React from 'react'; import {Link} from 'react-router-dom'; import styled from 'styled-components'; -import {isAssetMissing, isAssetStale} from './Stale'; +import {isAssetMissing, isAssetStaleAll} from './Stale'; import {asAssetKeyInput} from './asInput'; import {assetDetailsPathForKey} from './assetDetailsPathForKey'; import {AssetKey} from './types'; import { AssetStaleStatusQuery, AssetStaleStatusQueryVariables, -} from './types/CalculateChangedAndMissingDialog.types'; +} from './types/CalculateUnsyncedDialog.types'; import {showCustomAlert} from '../app/CustomAlertProvider'; import {displayNameForAssetKey} from '../asset-graph/Utils'; import {Container, Inner, Row} from '../ui/VirtualizedTable'; -export const CalculateChangedAndMissingDialog = React.memo( +export const CalculateUnsyncedDialog = React.memo( ({ isOpen, onClose, @@ -52,10 +52,10 @@ export const CalculateChangedAndMissingDialog = React.memo( }, ); - const staleOrMissing = React.useMemo( + const unsynced = React.useMemo( () => - data?.assetNodes - .filter((node) => isAssetStale(node.assetKey, node, 'all') || isAssetMissing(node)) + (data?.assetNodes || []) + .filter((node) => isAssetStaleAll(node) || isAssetMissing(node)) .map(asAssetKeyInput), [data], ); @@ -72,7 +72,7 @@ export const CalculateChangedAndMissingDialog = React.memo( const containerRef = React.useRef(null); const virtualizer = useVirtualizer({ - count: staleOrMissing?.length ?? 0, + count: unsynced.length, getScrollElement: () => containerRef.current, estimateSize: () => 28, }); @@ -81,8 +81,8 @@ export const CalculateChangedAndMissingDialog = React.memo( const [checked, setChecked] = React.useState>(new Set()); React.useLayoutEffect(() => { - setChecked(new Set(staleOrMissing)); - }, [staleOrMissing]); + setChecked(new Set(unsynced)); + }, [unsynced]); const content = () => { if (!isOpen) { @@ -95,19 +95,19 @@ export const CalculateChangedAndMissingDialog = React.memo( ); } - if (staleOrMissing?.length) { + if (unsynced.length) { return ( <> { setChecked((checked) => { - if (checked.size === staleOrMissing.length) { + if (checked.size === unsynced.length) { return new Set(); } else { - return new Set(staleOrMissing); + return new Set(unsynced); } }); }} @@ -119,7 +119,7 @@ export const CalculateChangedAndMissingDialog = React.memo( {items.map(({index, key, size, start}) => { - const item = staleOrMissing[index]!; + const item = unsynced[index]!; return ( {loading ? ( - ) : staleOrMissing?.length ? ( + ) : unsynced.length ? (