Skip to content

Commit

Permalink
[ui] Ability to report asset materializations from the actions dropdo…
Browse files Browse the repository at this point in the history
…wn [2] (#22781)

This is a second pass at merging
#22691 -- I merged it earlier
this week without realizing the internal PR
(dagster-io/internal#10341) still had a
buildkite error on it, and they need to merge together.
  • Loading branch information
bengotow authored Jul 3, 2024
1 parent 58ad7b0 commit a538286
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import email from '../icon-svgs/email.svg';
import error from '../icon-svgs/error.svg';
import error_outline from '../icon-svgs/error_outline.svg';
import execute from '../icon-svgs/execute.svg';
import executing from '../icon-svgs/executing.svg';
import expand from '../icon-svgs/expand.svg';
import expand_arrows from '../icon-svgs/expand_arrows.svg';
import expand_less from '../icon-svgs/expand_less.svg';
Expand Down Expand Up @@ -205,6 +206,7 @@ export const Icons = {
datatype_number,
expectation,
execute,
executing,
materialization,
observation,
job,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import {Button, Icon, Menu, MenuItem, Popover, Spinner, Tooltip} from '@dagster-io/ui-components';
import {
Button,
Icon,
Menu,
MenuDivider,
MenuItem,
Popover,
Spinner,
Tooltip,
} from '@dagster-io/ui-components';
import {useContext} from 'react';

import {
Expand All @@ -8,6 +17,7 @@ import {
import {useObserveAction} from './LaunchAssetObservationButton';
import {assetDetailsPathForKey} from './assetDetailsPathForKey';
import {AssetTableDefinitionFragment} from './types/AssetTableFragment.types';
import {useReportEventsModal} from './useReportEventsModal';
import {CloudOSSContext} from '../app/CloudOSSContext';
import {showSharedToaster} from '../app/DomUtils';
import {usePermissionsForLocation} from '../app/Permissions';
Expand All @@ -30,14 +40,24 @@ export const AssetActionMenu = (props: Props) => {
} = usePermissionsForLocation(repoAddress?.location);

const {
featureContext: {canSeeWipeMaterializationAction},
featureContext: {canSeeWipeMaterializationAction, canSeeMaterializeAction},
} = useContext(CloudOSSContext);

const {executeItem, launchpadElement} = useExecuteAssetMenuItem(path, definition);

const reportEvents = useReportEventsModal(
repoAddress
? {
assetKey: {path},
isPartitioned: !!definition?.partitionDefinition,
repository: {name: repoAddress.name, location: {name: repoAddress.location}},
}
: null,
);
return (
<>
{launchpadElement}
{reportEvents.element}
<Popover
position="bottom-right"
content={
Expand All @@ -55,7 +75,13 @@ export const AssetActionMenu = (props: Props) => {
icon="asset_group"
/>
<MenuLink
text="View neighbors"
text="View checks"
to={assetDetailsPathForKey({path}, {view: 'checks'})}
disabled={!definition}
icon="asset_check"
/>
<MenuLink
text="View lineage"
to={assetDetailsPathForKey({path}, {view: 'lineage', lineageScope: 'neighbors'})}
disabled={!definition}
icon="graph_neighbors"
Expand All @@ -72,6 +98,17 @@ export const AssetActionMenu = (props: Props) => {
disabled={!definition}
icon="graph_downstream"
/>
{canSeeMaterializeAction && definition?.hasMaterializePermission
? reportEvents.dropdownOptions.map((option) => (
<MenuItem
key={option.label}
text={option.label}
icon={option.icon}
onClick={option.onClick}
/>
))
: undefined}
{canSeeWipeMaterializationAction ? <MenuDivider /> : undefined}
{canSeeWipeMaterializationAction ? (
<MenuItem
text="Wipe materializations"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@ import {
Box,
Colors,
Icon,
MiddleTruncate,
Popover,
Spinner,
Tag,
intentToFillColor,
} from '@dagster-io/ui-components';
import {Link} from 'react-router-dom';

import {ChecksSummaryPopover} from './AssetChecksStatusSummary';
import {assertUnreachable} from '../../app/Util';
import {AssetCheckLiveFragment} from '../../asset-data/types/AssetBaseDataProvider.types';
import {
AssetCheckEvaluation,
AssetCheckExecution,
AssetCheckExecutionResolvedStatus,
AssetCheckSeverity,
AssetKey,
AssetKeyInput,
} from '../../graphql/types';
import {linkToRunEvent} from '../../runs/RunUtils';
import {TimestampDisplay} from '../../schedules/TimestampDisplay';
Expand All @@ -31,7 +34,7 @@ const CheckRow = ({
}: {
icon: JSX.Element;
checkName: string;
assetKey: AssetKey;
assetKey: AssetKeyInput;
timestamp?: number;
}) => (
<Box
Expand All @@ -56,7 +59,7 @@ export const CheckStatusRow = ({
assetKey,
}: {
assetCheck: AssetCheckLiveFragment;
assetKey: AssetKey;
assetKey: AssetKeyInput;
}) => {
const {executionForLatestMaterialization: execution} = assetCheck;

Expand Down Expand Up @@ -228,29 +231,56 @@ export const AssetCheckStatusTag = ({
export const AssetCheckErrorsTag = ({
checks,
severity,
assetKey,
}: {
checks: AssetCheckLiveFragment[];
severity: AssetCheckSeverity;
assetKey: AssetKeyInput;
}) => {
const actions: TagAction[] = [];
const execution = checks[0]?.executionForLatestMaterialization;
if (execution) {
const tagIcon = severity === AssetCheckSeverity.ERROR ? 'cancel' : 'warning_outline';
const tagIntent = severity === AssetCheckSeverity.ERROR ? 'danger' : 'warning';

if (checks.length === 1) {
const actions: TagAction[] = [];
const execution = checks[0]!.executionForLatestMaterialization;

actions.push({
label: 'View in run logs',
to: linkToRunEvent(
{id: execution.runId},
{stepKey: execution.stepKey, timestamp: execution.timestamp},
),
label: 'View details',
to: assetDetailsPathForAssetCheck({assetKey, name: checks[0]!.name}),
});
if (execution) {
actions.push({
label: 'View in run logs',
to: linkToRunEvent(
{id: execution.runId},
{stepKey: execution.stepKey, timestamp: execution.timestamp},
),
});
}

return (
<TagActionsPopover
data={{key: '', value: ''}}
actions={actions}
childrenMiddleTruncate={checks.length === 1}
>
<Tag icon={tagIcon} intent={tagIntent}>
<MiddleTruncate text={checks[0]!.name} />
</Tag>
</TagActionsPopover>
);
}

return (
<TagActionsPopover data={{key: '', value: ''}} actions={actions}>
<Tag
icon={severity === AssetCheckSeverity.ERROR ? 'cancel' : 'warning_outline'}
intent={severity === AssetCheckSeverity.ERROR ? 'danger' : 'warning'}
>
{checks.length === 1 ? checks[0]!.name : `${checks.length} failed`}
<Popover
content={<ChecksSummaryPopover type={severity} assetKey={assetKey} assetChecks={checks} />}
position="top-left"
interactionKind="hover"
className="chunk-popover-target"
>
<Tag icon={tagIcon} intent={tagIntent}>
{`${checks.length} failed`}
</Tag>
</TagActionsPopover>
</Popover>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import {CheckStatusRow} from './AssetCheckStatusTag';
import {assertUnreachable} from '../../app/Util';
import {AssetCheckLiveFragment} from '../../asset-data/types/AssetBaseDataProvider.types';
import {LiveDataForNode} from '../../asset-graph/Utils';
import {AssetCheckExecutionResolvedStatus, AssetCheckSeverity, AssetKey} from '../../graphql/types';
import {
AssetCheckExecutionResolvedStatus,
AssetCheckSeverity,
AssetKeyInput,
} from '../../graphql/types';

type AssetCheckIconType =
| Exclude<
Expand Down Expand Up @@ -82,13 +86,13 @@ const titlePerCheckType = (type: AssetCheckIconType) => {
}
};

const ChecksSummaryPopover = ({
export const ChecksSummaryPopover = ({
type,
assetKey,
assetChecks,
}: {
type: AssetCheckIconType;
assetKey: AssetKey;
assetKey: AssetKeyInput;
assetChecks: AssetCheckLiveFragment[];
}) => {
return (
Expand Down Expand Up @@ -123,7 +127,7 @@ export const AssetChecksStatusSummary = ({
}: {
liveData: LiveDataForNode;
rendering: 'dag' | 'tags';
assetKey: AssetKey;
assetKey: AssetKeyInput;
}) => {
const byIconType = countBy(liveData.assetChecks, iconTypeFromCheck);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type Asset = {
repository: {name: string; location: {name: string}};
};

export function useReportEventsModal(asset: Asset | null, onEventReported: () => void) {
export function useReportEventsModal(asset: Asset | null, onEventReported?: () => void) {
const [isOpen, setIsOpen] = useState(false);

const dropdownOptions = useMemo(
Expand Down Expand Up @@ -85,7 +85,7 @@ const ReportEventDialogBody = ({
repoAddress: RepoAddress;
isOpen: boolean;
setIsOpen: (open: boolean) => void;
onEventReported: () => void;
onEventReported?: () => void;
}) => {
const [description, setDescription] = useState('');
const {
Expand Down Expand Up @@ -159,7 +159,7 @@ const ReportEventDialogBody = ({
icon: 'materialization',
intent: 'success',
});
onEventReported();
onEventReported?.();
setIsOpen(false);
}
};
Expand Down
3 changes: 3 additions & 0 deletions js_modules/dagster-ui/packages/ui-core/src/ui/TagActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,19 @@ export const TagActionsPopover = ({
data,
actions,
children,
childrenMiddleTruncate,
}: {
data: TagType;
actions: TagAction[];
children: React.ReactNode;
childrenMiddleTruncate?: boolean;
}) => {
return (
<Popover
content={<TagActions actions={actions} data={data} />}
hoverOpenDelay={100}
hoverCloseDelay={100}
targetProps={childrenMiddleTruncate ? {style: {minWidth: 0, maxWidth: '100%'}} : {}}
placement="top"
interactionKind="hover"
>
Expand Down

2 comments on commit a538286

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for dagit-storybook ready!

✅ Preview
https://dagit-storybook-5wfdnqna5-elementl.vercel.app

Built with commit a538286.
This pull request is being automatically deployed with vercel-action

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for dagit-core-storybook ready!

✅ Preview
https://dagit-core-storybook-e6jge9au1-elementl.vercel.app

Built with commit a538286.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.