Skip to content

Commit

Permalink
[ui] Show backfill policies, preview of backfill partition ranges (#1…
Browse files Browse the repository at this point in the history
…7540)

## Summary & Motivation

This PR adds:

- A new Backfill policy section to the asset sidebar and asset
definition page, which displays the asset's backfill policy description,
if a policy is present.

- A new Backfill Preview modal, which allows the user to see which
ranges of each asset will be backfilled, and what backfill policy will
be used for each asset. This modal is accessible via a Preview button in
the Launch Partitions modal IF there are multiple backfill policies or
if the partition mapping is in use.

- Smaller changes:
+ The Launch backfill button no longer says how many runs will be
launched, since this number is not always known.
+ The partition selection modal no longer offers the "show more asset
health bars" link which confusingly pasted asset health bars into the
modal. This option is totally removed.
+ The "Backfill options" section is now just called "Options" (since we
didn't say "Backfill partitions", etc.) and disappears entirely if there
are no options to be displayed rather than appearing empty.
   
## How I Tested These Changes

I updated the existing tests, and wrote new tests verifying that the
preview option is shown in the correct scenarios and opens the new
modal. I also added new stories covering the backfill preview dialog
contents.

New Preview button:

<img width="823" alt="image"
src="https://github.com/dagster-io/dagster/assets/1037212/c765448a-bcb1-4109-99c7-edbd3fc7b276">

When partition mapping is present, the text changes to this:
<img width="796" alt="image"
src="https://github.com/dagster-io/dagster/assets/1037212/5d70434b-1925-4493-a814-4aad7b6fb1ef">


New Preview panel:

<img width="1289" alt="image"
src="https://github.com/dagster-io/dagster/assets/1037212/e3fcafe6-14c3-4478-b3a4-105c83c34d35">

---------

Co-authored-by: bengotow <[email protected]>
  • Loading branch information
2 people authored and dpeng817 committed Oct 31, 2023
1 parent eb994d4 commit adba090
Show file tree
Hide file tree
Showing 23 changed files with 792 additions and 347 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,5 @@ export const calculateMiddleTruncation = (
end = mid - 1;
}
}

return `${text.slice(0, end)}${text.slice(-end)}`;
};
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ const SIDEBAR_ASSET_FRAGMENT = gql`
description
}
}
backfillPolicy {
description
}
partitionDefinition {
description
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const buildSidebarQueryMock = (
__typename: 'AssetNode',
id: 'test.py.repo.["asset1"]',
description: null,
backfillPolicy: null,
configField: null,
metadataEntries: [],
assetChecks: [],
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const AssetNodeDefinition: React.FC<{
</Box>
</>
)}

{assetNode.freshnessPolicy && (
<>
<Box padding={{vertical: 16, horizontal: 24}} border="top-and-bottom">
Expand Down Expand Up @@ -127,6 +128,21 @@ export const AssetNodeDefinition: React.FC<{
</Box>
</>
)}

{assetNode.backfillPolicy && (
<>
<Box padding={{vertical: 16, horizontal: 24}} border="top-and-bottom">
<Subheading>Backfill policy</Subheading>
</Box>
<Box
padding={{vertical: 16, horizontal: 24}}
flex={{gap: 12, alignItems: 'flex-start'}}
>
<Body style={{flex: 1}}>{assetNode.backfillPolicy.description}</Body>
</Box>
</>
)}

<Box
padding={{vertical: 16, horizontal: 24}}
border="top-and-bottom"
Expand Down Expand Up @@ -326,7 +342,9 @@ export const ASSET_NODE_DEFINITION_FRAGMENT = gql`
cronSchedule
cronScheduleTimezone
}
backfillPolicy {
description
}
partitionDefinition {
description
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ export const AssetSidebarActivitySummary: React.FC<Props> = ({
</SidebarSection>
)}

{asset.backfillPolicy && (
<SidebarSection title="Backfill policy">
<Box margin={{horizontal: 24, vertical: 12}} flex={{gap: 12, alignItems: 'flex-start'}}>
<Body style={{flex: 1}}>{asset.backfillPolicy.description}</Body>
</Box>
</SidebarSection>
)}

{loadedPartitionKeys.length > 1 ? null : (
<>
<SidebarSection
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import {gql, useQuery} from '@apollo/client';
import {Box, Button, Colors, Dialog, DialogFooter, Spinner} from '@dagster-io/ui-components';
import {useVirtualizer} from '@tanstack/react-virtual';
import React from 'react';
import styled from 'styled-components';

import {tokenForAssetKey} from '../asset-graph/Utils';
import {TargetPartitionsDisplay} from '../instance/backfill/TargetPartitionsDisplay';
import {testId} from '../testing/testId';
import {Container, HeaderCell, Inner, Row, RowCell} from '../ui/VirtualizedTable';

import {AssetLink} from './AssetLink';
import {asAssetKeyInput} from './asInput';
import {AssetKey} from './types';
import {
BackfillPreviewQuery,
BackfillPreviewQueryVariables,
} from './types/BackfillPreviewModal.types';
import {
BackfillPolicyForLaunchAssetFragment,
PartitionDefinitionForLaunchAssetFragment,
} from './types/LaunchAssetExecutionButton.types';

interface BackfillPreviewModalProps {
isOpen: boolean;
assets: {
assetKey: AssetKey;
partitionDefinition: PartitionDefinitionForLaunchAssetFragment | null;
backfillPolicy: BackfillPolicyForLaunchAssetFragment | null;
}[];
keysFiltered: string[];
setOpen: (isOpen: boolean) => void;
}
const TEMPLATE_COLUMNS = '1fr 1fr 1fr 1fr';

export const BackfillPreviewModal = ({
isOpen,
setOpen,
assets,
keysFiltered,
}: BackfillPreviewModalProps) => {
const assetKeys = React.useMemo(() => assets.map(asAssetKeyInput), [assets]);
const parentRef = React.useRef<HTMLDivElement | null>(null);

const rowVirtualizer = useVirtualizer({
count: assets.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 60,
overscan: 10,
});
const totalHeight = rowVirtualizer.getTotalSize();
const items = rowVirtualizer.getVirtualItems();

const {data} = useQuery<BackfillPreviewQuery, BackfillPreviewQueryVariables>(
BACKFILL_PREVIEW_QUERY,
{
variables: {partitionNames: keysFiltered, assetKeys},
skip: !isOpen,
},
);

const partitionsByAssetToken = React.useMemo(() => {
return Object.fromEntries(
(data?.assetBackfillPreview || []).map((d) => [tokenForAssetKey(d.assetKey), d.partitions]),
);
}, [data]);

// BG Note: The transform: scale(1) below fixes a bug with MiddleTruncate where the text size
// is measured while the dialog is animating open and the scale is < 1, causing it to think
// it needs to truncate. A more general fix for this seems like it'll require a lot of testing.

return (
<Dialog
title="Backfill preview"
isOpen={isOpen}
onClose={() => setOpen(false)}
style={{width: '90vw', maxWidth: 1100, transform: 'scale(1)'}}
>
<Container
ref={parentRef}
style={{maxHeight: '50vh'}}
data-testid={testId('backfill-preview-modal-content')}
>
<BackfillPreviewTableHeader />
<Inner $totalHeight={totalHeight}>
{items.map(({index, size, start}) => {
const {assetKey, partitionDefinition, backfillPolicy} = assets[index]!;
const token = tokenForAssetKey(assetKey);
const partitions = partitionsByAssetToken[token];

return (
<Row key={token} $height={size} $start={start}>
<RowGrid border={index < assets.length - 1 ? 'bottom' : undefined}>
<RowCell>
<AssetLink path={assetKey.path} textStyle="middle-truncate" icon="asset" />
</RowCell>
{backfillPolicy ? (
<RowCell style={{color: Colors.Dark}}>{backfillPolicy?.description}</RowCell>
) : (
<RowCell>{'\u2013'}</RowCell>
)}
{partitionDefinition ? (
<RowCell style={{color: Colors.Dark}}>
{partitionDefinition?.description}
</RowCell>
) : (
<RowCell>{'\u2013'}</RowCell>
)}
<RowCell style={{color: Colors.Dark, alignItems: 'flex-start'}}>
{partitions ? (
<TargetPartitionsDisplay targetPartitions={partitions} />
) : (
<Spinner purpose="body-text" />
)}
</RowCell>
</RowGrid>
</Row>
);
})}
</Inner>
</Container>
<DialogFooter topBorder>
<Button intent="primary" autoFocus={true} onClick={() => setOpen(false)}>
OK
</Button>
</DialogFooter>
</Dialog>
);
};

const RowGrid = styled(Box)`
display: grid;
grid-template-columns: ${TEMPLATE_COLUMNS};
height: 100%;
`;

export const BackfillPreviewTableHeader = () => {
return (
<Box
border="bottom"
style={{
display: 'grid',
gridTemplateColumns: TEMPLATE_COLUMNS,
height: '32px',
fontSize: '12px',
color: Colors.Gray600,
}}
>
<HeaderCell>Asset key</HeaderCell>
<HeaderCell>Backfill policy</HeaderCell>
<HeaderCell>Partition definition</HeaderCell>
<HeaderCell>Partitions to launch</HeaderCell>
</Box>
);
};

export const BACKFILL_PREVIEW_QUERY = gql`
query BackfillPreviewQuery($partitionNames: [String!]!, $assetKeys: [AssetKeyInput!]!) {
assetBackfillPreview(params: {partitionNames: $partitionNames, assetSelection: $assetKeys}) {
assetKey {
path
}
partitions {
partitionKeys
ranges {
start
end
}
}
}
}
`;
Loading

0 comments on commit adba090

Please sign in to comment.