From 1bd28b81952392de5683886298dd1acfbc5e6d34 Mon Sep 17 00:00:00 2001 From: bengotow Date: Sun, 3 Nov 2024 09:10:50 -0600 Subject: [PATCH] [ui] Polish runs feed UI --- .../src/components/PageHeader.tsx | 3 +- .../ui-core/src/assets/AssetNodeOverview.tsx | 16 +++-- .../instance/backfill/ExecutionTimeline.tsx | 7 +- .../ui-core/src/runs/AssetTagCollections.tsx | 10 +-- .../ui-core/src/runs/CreatedByTag.tsx | 1 + .../ui-core/src/runs/RunTargetLink.tsx | 2 +- .../packages/ui-core/src/runs/RunsFeedRow.tsx | 14 +++- .../ui-core/src/runs/RunsFeedTable.tsx | 64 +++++++++++++++---- .../ui-core/src/runs/RunsFilterInput.tsx | 6 +- .../ui-core/src/runs/UserDisplay.oss.tsx | 10 ++- .../ui-core/src/runs/useRunsFeedEntries.tsx | 2 +- 11 files changed, 102 insertions(+), 33 deletions(-) diff --git a/js_modules/dagster-ui/packages/ui-components/src/components/PageHeader.tsx b/js_modules/dagster-ui/packages/ui-components/src/components/PageHeader.tsx index 3de87bda4b45d..b32443c4c3a1f 100644 --- a/js_modules/dagster-ui/packages/ui-components/src/components/PageHeader.tsx +++ b/js_modules/dagster-ui/packages/ui-components/src/components/PageHeader.tsx @@ -25,8 +25,9 @@ export const PageHeader = (props: Props) => { > {title && ( {title} 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 5df0bc40ec4be..9015c9f7e195c 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 @@ -317,17 +317,19 @@ export const AssetNodeOverview = ({ - + - - {location && ( - - Loaded {dayjs.unix(location.updatedTimestamp).fromNow()} - - )} + + + {location && ( + + Loaded {dayjs.unix(location.updatedTimestamp).fromNow()} + + )} + diff --git a/js_modules/dagster-ui/packages/ui-core/src/instance/backfill/ExecutionTimeline.tsx b/js_modules/dagster-ui/packages/ui-core/src/instance/backfill/ExecutionTimeline.tsx index e72c3221b1d22..3e8cdbef5f4da 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/instance/backfill/ExecutionTimeline.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/instance/backfill/ExecutionTimeline.tsx @@ -1,4 +1,4 @@ -import {Box, Colors, Spinner, useViewport} from '@dagster-io/ui-components'; +import {Box, Colors, Mono, Spinner, useViewport} from '@dagster-io/ui-components'; import {useVirtualizer} from '@tanstack/react-virtual'; import React from 'react'; import {Link} from 'react-router-dom'; @@ -12,6 +12,7 @@ import { TimelineRowContainer, } from '../../runs/RunTimeline'; import {TimelineRun} from '../../runs/RunTimelineTypes'; +import {titleForRun} from '../../runs/RunUtils'; import {TimeElapsed} from '../../runs/TimeElapsed'; import {RunBatch, batchRunsForTimeline} from '../../runs/batchRunsForTimeline'; import {mergeStatusToBackground} from '../../runs/mergeStatusToBackground'; @@ -165,7 +166,9 @@ export const ExecutionTimelineRow = ({ > - {run.id.slice(0, 8)} + + {titleForRun(run)} + 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 e0e6debf7737f..394ca93f0db74 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 @@ -88,6 +88,7 @@ export const AssetKeyTagCollection = React.memo((props: AssetKeyTagCollectionPro const assetKey = assetKeys[0]!; return ( {useTags ? ( - {displayNameForAssetKey(assetKey)} + ) : ( - {displayNameForAssetKey(assetKey)} + )} @@ -176,16 +177,17 @@ export const AssetCheckTagCollection = React.memo((props: AssetCheckTagCollectio {useTags ? ( - {labelForAssetCheck(check)} + ) : ( - {labelForAssetCheck(check)} + )} diff --git a/js_modules/dagster-ui/packages/ui-core/src/runs/CreatedByTag.tsx b/js_modules/dagster-ui/packages/ui-core/src/runs/CreatedByTag.tsx index d3295d3ef242a..ca55de80285bb 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/runs/CreatedByTag.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/runs/CreatedByTag.tsx @@ -122,6 +122,7 @@ export const CreatedByTag = ({repoAddress, tags, onAddTag}: Props) => { return ( { return isHiddenAssetGroupJob(run.pipelineName) ? ( - + diff --git a/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFeedRow.tsx b/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFeedRow.tsx index 22237ecfd97ef..040fe2d838f1b 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFeedRow.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFeedRow.tsx @@ -104,6 +104,12 @@ export const RunsFeedRow = ({ flex={{direction: 'row', alignItems: 'center', wrap: 'wrap'}} style={{gap: '4px 8px', lineHeight: 0}} > + {entry.__typename === 'PartitionBackfill' ? ( + + Backfill + + ) : undefined} + ) : ( @@ -187,7 +197,7 @@ export const RunsFeedRow = ({ }; const TEMPLATE_COLUMNS = - '60px minmax(0, 2fr) minmax(0, 2fr) minmax(0, 1fr) 140px 150px 120px 132px'; + '60px minmax(0, 2fr) minmax(0, 1.2fr) minmax(0, 1fr) 140px 150px 120px 132px'; export const RunsFeedTableHeader = ({checkbox}: {checkbox: React.ReactNode}) => { return ( diff --git a/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFeedTable.tsx b/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFeedTable.tsx index ade8e687ad5fd..a0344fe9f14c7 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFeedTable.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFeedTable.tsx @@ -8,7 +8,7 @@ import { ifPlural, } from '@dagster-io/ui-components'; import {useVirtualizer} from '@tanstack/react-virtual'; -import React, {useMemo, useRef} from 'react'; +import React, {useEffect, useMemo, useRef} from 'react'; import {RunBulkActionsMenu} from './RunActionsMenu'; import {RunTableEmptyState} from './RunTableEmptyState'; @@ -81,6 +81,20 @@ export const RunsFeedTable = ({ ); const backfillsExcluded = selectedEntries.length - selectedRuns.length; + const resetScrollOnLoad = useRef(false); + useEffect(() => { + // When you click "Next page" from the bottom of page 1, we show the indeterminate + // loading state and want to scroll to the top when the new results arrive. It looks + // bad to do it immediately, and the `entries` can also change on their own (and + // sometimes with new rows), so we do this explicitly for pagination cases using a ref. + if (!loading && resetScrollOnLoad.current) { + resetScrollOnLoad.current = false; + if (parentRef.current) { + parentRef.current.scrollTop = 0; + } + } + }, [loading]); + const actionBar = ( {actionBarComponents ?? } - + { + resetScrollOnLoad.current = true; + paginationProps.popCursor(); + }} + advanceCursor={() => { + resetScrollOnLoad.current = true; + paginationProps.advanceCursor(); + }} + reset={() => { + resetScrollOnLoad.current = true; + paginationProps.reset(); + }} + /> onToggleAll(false)} selected={selectedRuns} @@ -122,27 +152,37 @@ export const RunsFeedTable = ({ ); function content() { + const header = ( + + } + /> + ); + if (entries.length === 0 && !loading) { const anyFilter = !!Object.keys(filter || {}).length; if (emptyState) { return <>{emptyState()}; } - return ; + return ( +
+ {header} + +
+ ); } + return (
- - } - /> + {header} {entries.length === 0 && loading && ( diff --git a/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFilterInput.tsx b/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFilterInput.tsx index 729fa14616682..0c3f7b5d19a94 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFilterInput.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/runs/RunsFilterInput.tsx @@ -104,7 +104,11 @@ export function useQueryPersistedRunFilters(enabledFilters?: RunFilterTokenType[ return useQueryPersistedState( useMemo( () => ({ - encode: (tokens) => ({q: tokensAsStringArray(tokens), cursor: undefined}), + encode: (tokens) => ({ + q: tokensAsStringArray(tokens), + cursor: undefined, + runs_before: undefined, + }), decode: ({q = []}) => tokenizedValuesFromStringArray(q, RUN_PROVIDERS_EMPTY).filter( (t) => diff --git a/js_modules/dagster-ui/packages/ui-core/src/runs/UserDisplay.oss.tsx b/js_modules/dagster-ui/packages/ui-core/src/runs/UserDisplay.oss.tsx index f7a82bba8f4ef..bcea77acac6a9 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/runs/UserDisplay.oss.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/runs/UserDisplay.oss.tsx @@ -1,4 +1,4 @@ -import {BaseTag, Box, SubwayDot} from '@dagster-io/ui-components'; +import {BaseTag, Box, MiddleTruncate, SubwayDot} from '@dagster-io/ui-components'; type Props = { email: string; @@ -16,6 +16,12 @@ export function UserDisplay({email, isFilter}: Props) { {email} ) : ( - {icon}
} label={email} /> + + {icon}} + label={} + /> + ); } diff --git a/js_modules/dagster-ui/packages/ui-core/src/runs/useRunsFeedEntries.tsx b/js_modules/dagster-ui/packages/ui-core/src/runs/useRunsFeedEntries.tsx index c152b6bfded4f..9f5f84dc661d7 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/runs/useRunsFeedEntries.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/runs/useRunsFeedEntries.tsx @@ -11,7 +11,7 @@ import {gql, useQuery} from '../apollo-client'; import {PYTHON_ERROR_FRAGMENT} from '../app/PythonErrorFragment'; import {RunsFilter} from '../graphql/types'; -const PAGE_SIZE = 25; +const PAGE_SIZE = 29; const RUNS_FEED_CURSOR_KEY = `runs_before`;