From 69a092ce8006cc4bd5dd826a4187a9bb9ed531ab Mon Sep 17 00:00:00 2001 From: bengotow Date: Thu, 9 Jan 2025 09:13:44 -0600 Subject: [PATCH] wip --- .../src/components/CollapsibleSection.tsx | 4 +- .../dagster-ui/packages/ui-core/client.json | 4 +- .../ui-core/src/assets/AssetListUtils.tsx | 33 ++++ .../src/automation/AutomationTargetList.tsx | 172 ++++++++++-------- .../AutomationAssetSelectionFragment.types.ts | 5 + .../ui-core/src/graphql/schema.graphql | 1 + .../packages/ui-core/src/graphql/types.ts | 2 + .../ui-core/src/runs/AssetTagCollections.tsx | 31 +--- .../ScheduleAssetSelectionsQuery.types.ts | 7 +- .../src/sensors/types/SensorRoot.types.ts | 7 +- 10 files changed, 165 insertions(+), 101 deletions(-) create mode 100644 js_modules/dagster-ui/packages/ui-core/src/assets/AssetListUtils.tsx diff --git a/js_modules/dagster-ui/packages/ui-components/src/components/CollapsibleSection.tsx b/js_modules/dagster-ui/packages/ui-components/src/components/CollapsibleSection.tsx index 449db327a3989..c16f4f709b809 100644 --- a/js_modules/dagster-ui/packages/ui-components/src/components/CollapsibleSection.tsx +++ b/js_modules/dagster-ui/packages/ui-components/src/components/CollapsibleSection.tsx @@ -5,12 +5,14 @@ import {Icon} from './Icon'; export const CollapsibleSection = ({ header, + containerProps, headerWrapperProps, children, isInitiallyCollapsed = false, arrowSide = 'left', }: { header: React.ReactNode; + containerProps?: React.ComponentProps; headerWrapperProps?: React.ComponentProps; children: React.ReactNode; isInitiallyCollapsed?: boolean; @@ -18,7 +20,7 @@ export const CollapsibleSection = ({ }) => { const [isCollapsed, setIsCollapsed] = React.useState(isInitiallyCollapsed); return ( - + { + return COMMON_COLLATOR.compare(displayNameForAssetKey(a), displayNameForAssetKey(b)); +}; + +export const sortItemAssetCheck = (a: Check, b: Check) => { + return COMMON_COLLATOR.compare(labelForAssetCheck(a), labelForAssetCheck(b)); +}; + +export const renderItemAssetKey = (assetKey: AssetKey) => ( + + + +); + +export const renderItemAssetCheck = (assetCheck: Check) => ( + + + +); + +export const labelForAssetCheck = (check: Check) => { + return `${check.name} on ${displayNameForAssetKey(check.assetKey)}`; +}; diff --git a/js_modules/dagster-ui/packages/ui-core/src/automation/AutomationTargetList.tsx b/js_modules/dagster-ui/packages/ui-core/src/automation/AutomationTargetList.tsx index abee80ef1957f..efa9d3c7ba4b4 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/automation/AutomationTargetList.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/automation/AutomationTargetList.tsx @@ -7,7 +7,6 @@ import { Dialog, DialogFooter, DisclosureTriangleButton, - MiddleTruncate, Subtitle2, Tag, } from '@dagster-io/ui-components'; @@ -15,17 +14,22 @@ import {useMemo, useState} from 'react'; import {Link} from 'react-router-dom'; import { - AssetSelectionNodeFragment, - AutomationAssetSelectionFragment, -} from './types/AutomationAssetSelectionFragment.types'; + renderItemAssetCheck, + renderItemAssetKey, + sortItemAssetCheck, + sortItemAssetKey, +} from '../assets/AssetListUtils'; +import {VirtualizedItemListForDialog} from '../ui/VirtualizedItemListForDialog'; +import {AutomationAssetSelectionFragment} from './types/AutomationAssetSelectionFragment.types'; import {showCustomAlert} from '../app/CustomAlertProvider'; import {PythonErrorInfo} from '../app/PythonErrorInfo'; -import {COMMON_COLLATOR} from '../app/Util'; -import {displayNameForAssetKey, isHiddenAssetGroupJob} from '../asset-graph/Utils'; -import {assetDetailsPathForKey} from '../assets/assetDetailsPathForKey'; +import {isHiddenAssetGroupJob} from '../asset-graph/Utils'; +import { + assetDetailsPathForAssetCheck, + assetDetailsPathForKey, +} from '../assets/assetDetailsPathForKey'; import {SensorType} from '../graphql/types'; import {PipelineReference} from '../pipelines/PipelineReference'; -import {VirtualizedItemListForDialog} from '../ui/VirtualizedItemListForDialog'; import {numberFormatter} from '../ui/formatters'; import {isThisThingAJob, useRepository} from '../workspace/WorkspaceContext/util'; import {RepoAddress} from '../workspace/types'; @@ -94,34 +98,41 @@ const AssetSelectionTag = ({ const error = assetSelection.assetsOrError.__typename === 'PythonError' ? assetSelection.assetsOrError : null; - const sortedAssets = useMemo(() => { + const {checks, assets, assetsWithAMP, assetsWithoutAMP} = useMemo(() => { if (assetSelection.assetsOrError.__typename === 'PythonError') { - return []; + return {checks: [], assets: [], assetsWithAMP: [], assetsWithoutAMP: []}; } - return assetSelection.assetsOrError.nodes - .slice() - .sort((a, b) => - COMMON_COLLATOR.compare(displayNameForAssetKey(a.key), displayNameForAssetKey(b.key)), - ); - }, [assetSelection.assetsOrError]); + const assets = assetSelection.assetsOrError.nodes; - const assetsWithAMP = useMemo( - () => sortedAssets.filter((asset) => !!asset.definition?.automationCondition), - [sortedAssets], - ); - const assetsWithoutAMP = useMemo( - () => sortedAssets.filter((asset) => !asset.definition?.automationCondition), - [sortedAssets], - ); + return { + checks: assetSelection.assetChecks.slice().sort(sortItemAssetCheck), + assets: assets.map((a) => a.key).sort(sortItemAssetKey), + assetsWithAMP: assets + .filter((asset) => !!asset.definition?.automationCondition) + .map((a) => a.key) + .sort(sortItemAssetKey), + assetsWithoutAMP: assets + .filter((asset) => !asset.definition?.automationCondition) + .map((a) => a.key) + .sort(sortItemAssetKey), + }; + }, [assetSelection]); const assetSelectionString = assetSelection.assetSelectionString || ''; const isAllAssets = assetSelectionString === ALL_ASSETS_STRING; - const firstAsset = sortedAssets[0]; - if (firstAsset && sortedAssets.length === 1) { + if (assets.length === 1) { return ( - {assetSelectionString} + {assetSelectionString} + + ); + } + + if (checks.length === 1) { + return ( + + {assetSelectionString} ); } @@ -146,16 +157,55 @@ const AssetSelectionTag = ({
+ } />
+ } /> ) : ( -
+
+ } + /> + )} + {checks.length > 0 && ( +
+ } + /> )} @@ -169,10 +219,7 @@ const AssetSelectionTag = ({ - + { if (error) { @@ -198,43 +245,40 @@ const AssetSelectionTag = ({ }; const Section = ({ - assets, + count, + list, title, titleBorder = 'top-and-bottom', }: { - assets: AssetSelectionNodeFragment[]; + count: number; + list: React.ReactNode; title?: string; titleBorder?: React.ComponentProps['border']; }) => { const [isOpen, setIsOpen] = useState(true); + + // BG Note: This doesn't use CollapsibleSection because we want to put + // the sections and their content in the same top-level flexbox to render + // two sections with two virtualized lists that each scroll. return ( <> {title ? ( - - { - setIsOpen(!isOpen); - }} - > - {}} isOpen={isOpen} /> + setIsOpen(!isOpen)} + > + - {title} ({numberFormatter.format(assets.length)}) + {title} ({numberFormatter.format(count)}) + {}} isOpen={isOpen} /> ) : null} {isOpen ? ( - assets.length ? ( -
- } - itemBorders - /> -
+ count ? ( +
{list}
) : ( 0 assets @@ -244,19 +288,3 @@ const Section = ({ ); }; - -const VirtualizedSelectedAssetRow = ({asset}: {asset: AssetSelectionNodeFragment}) => { - return ( - - - - - - - - ); -}; diff --git a/js_modules/dagster-ui/packages/ui-core/src/automation/types/AutomationAssetSelectionFragment.types.ts b/js_modules/dagster-ui/packages/ui-core/src/automation/types/AutomationAssetSelectionFragment.types.ts index 8195307a90ca9..d7569a9dc29b8 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/automation/types/AutomationAssetSelectionFragment.types.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/automation/types/AutomationAssetSelectionFragment.types.ts @@ -5,6 +5,11 @@ import * as Types from '../../graphql/types'; export type AutomationAssetSelectionFragment = { __typename: 'AssetSelection'; assetSelectionString: string | null; + assetChecks: Array<{ + __typename: 'AssetCheckhandle'; + name: string; + assetKey: {__typename: 'AssetKey'; path: Array}; + }>; assetsOrError: | { __typename: 'AssetConnection'; diff --git a/js_modules/dagster-ui/packages/ui-core/src/graphql/schema.graphql b/js_modules/dagster-ui/packages/ui-core/src/graphql/schema.graphql index 2ee398fb3a6f7..1fb6c67060d9a 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/graphql/schema.graphql +++ b/js_modules/dagster-ui/packages/ui-core/src/graphql/schema.graphql @@ -1660,6 +1660,7 @@ enum InstigationStatus { type AssetSelection { assetSelectionString: String assetKeys: [AssetKey!]! + assetChecks: [AssetCheckhandle!]! assets: [Asset!]! assetsOrError: AssetsOrError! } diff --git a/js_modules/dagster-ui/packages/ui-core/src/graphql/types.ts b/js_modules/dagster-ui/packages/ui-core/src/graphql/types.ts index 74ad1106c7aee..cf5450d5257d2 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/graphql/types.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/graphql/types.ts @@ -597,6 +597,7 @@ export type AssetPartitionsStatusCounts = { export type AssetSelection = { __typename: 'AssetSelection'; + assetChecks: Array; assetKeys: Array; assetSelectionString: Maybe; assets: Array; @@ -6888,6 +6889,7 @@ export const buildAssetSelection = ( relationshipsToOmit.add('AssetSelection'); return { __typename: 'AssetSelection', + assetChecks: overrides && overrides.hasOwnProperty('assetChecks') ? overrides.assetChecks! : [], assetKeys: overrides && overrides.hasOwnProperty('assetKeys') ? overrides.assetKeys! : [], assetSelectionString: overrides && overrides.hasOwnProperty('assetSelectionString') diff --git a/js_modules/dagster-ui/packages/ui-core/src/runs/AssetTagCollections.tsx b/js_modules/dagster-ui/packages/ui-core/src/runs/AssetTagCollections.tsx index 37521e97e3a06..5e0d05cf1054a 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/runs/AssetTagCollections.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/runs/AssetTagCollections.tsx @@ -14,6 +14,13 @@ import * as React from 'react'; import {Link} from 'react-router-dom'; import {displayNameForAssetKey, tokenForAssetKey} from '../asset-graph/Utils'; +import { + labelForAssetCheck, + renderItemAssetCheck, + renderItemAssetKey, + sortItemAssetCheck, + sortItemAssetKey, +} from '../assets/AssetListUtils'; import { assetDetailsPathForAssetCheck, assetDetailsPathForKey, @@ -24,30 +31,6 @@ import {TagActionsPopover} from '../ui/TagActions'; import {VirtualizedItemListForDialog} from '../ui/VirtualizedItemListForDialog'; import {numberFormatter} from '../ui/formatters'; -const sortItemAssetKey = (a: AssetKey, b: AssetKey) => { - return displayNameForAssetKey(a).localeCompare(displayNameForAssetKey(b)); -}; - -const sortItemAssetCheck = (a: Check, b: Check) => { - return labelForAssetCheck(a).localeCompare(labelForAssetCheck(b)); -}; - -const renderItemAssetKey = (assetKey: AssetKey) => ( - - - -); - -const renderItemAssetCheck = (assetCheck: Check) => ( - - - -); - -const labelForAssetCheck = (check: Check) => { - return `${check.name} on ${displayNameForAssetKey(check.assetKey)}`; -}; - function useShowMoreDialog( dialogTitle: string, items: T[] | null, diff --git a/js_modules/dagster-ui/packages/ui-core/src/schedules/types/ScheduleAssetSelectionsQuery.types.ts b/js_modules/dagster-ui/packages/ui-core/src/schedules/types/ScheduleAssetSelectionsQuery.types.ts index 67ec28e394e8b..522898332dc7e 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/schedules/types/ScheduleAssetSelectionsQuery.types.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/schedules/types/ScheduleAssetSelectionsQuery.types.ts @@ -25,6 +25,11 @@ export type ScheduleAssetSelectionQuery = { assetSelection: { __typename: 'AssetSelection'; assetSelectionString: string | null; + assetChecks: Array<{ + __typename: 'AssetCheckhandle'; + name: string; + assetKey: {__typename: 'AssetKey'; path: Array}; + }>; assetsOrError: | { __typename: 'AssetConnection'; @@ -54,4 +59,4 @@ export type ScheduleAssetSelectionQuery = { | {__typename: 'ScheduleNotFoundError'}; }; -export const ScheduleAssetSelectionQueryVersion = '6942bd68a512ac71d6449844dbc07fcfd18226ab14b46e844f432f73a81eeccf'; +export const ScheduleAssetSelectionQueryVersion = '33af4b2d37d581ed3da0226f0877ad73a1ad46ab9c8938a19509fc4f851c78bb'; diff --git a/js_modules/dagster-ui/packages/ui-core/src/sensors/types/SensorRoot.types.ts b/js_modules/dagster-ui/packages/ui-core/src/sensors/types/SensorRoot.types.ts index e6f956cf2ab57..440d75e916f5b 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/sensors/types/SensorRoot.types.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/sensors/types/SensorRoot.types.ts @@ -152,6 +152,11 @@ export type SensorAssetSelectionQuery = { assetSelection: { __typename: 'AssetSelection'; assetSelectionString: string | null; + assetChecks: Array<{ + __typename: 'AssetCheckhandle'; + name: string; + assetKey: {__typename: 'AssetKey'; path: Array}; + }>; assetsOrError: | { __typename: 'AssetConnection'; @@ -184,4 +189,4 @@ export type SensorAssetSelectionQuery = { export const SensorRootQueryVersion = 'fd32c8557a75c273133137c289091357635f3be0af17b9a57b052087f8e9d023'; -export const SensorAssetSelectionQueryVersion = '188cd7bab57cb2a04cf4941133f43327d91cf9edef01018d3635cacf6e36582d'; +export const SensorAssetSelectionQueryVersion = '2fb6c2c612ee7ab4a7ad1f59cfd7677a6a3d14319200f8c49b43850de8b3b0f3';