Skip to content

Commit

Permalink
[ui] Component injection site for run metrics (#21998)
Browse files Browse the repository at this point in the history
## Summary & Motivation

Related: FE-321

This PR adds a new InjectedComponent and uses it in the run actions menu
and run header menu. When a component for the dialog is provided (only
in Plus atm), the menu item appears and allows the dialog to be
displayed.

## How I Tested These Changes

Tested that this has no impact in OSS and appears in Dagster Plus.

Co-authored-by: bengotow <bgotow@elementl.com>
  • Loading branch information
bengotow and bengotow committed May 22, 2024
1 parent dab8900 commit 800b579
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ type InjectedComponentContextType = {
UserPreferences?: AComponentFromComponent<typeof UserPreferences> | null;
AssetsOverview?: AComponentFromComponent<typeof AssetsOverviewRoot> | null;
FallthroughRoot?: AComponentFromComponent<typeof FallthroughRoot> | null;
RunMetricsDialog?: AComponentWithProps<{
runId: string;
isOpen: boolean;
onClose: () => void;
}> | null;
};
export const InjectedComponentContext = React.createContext<InjectedComponentContextType>({});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface AssetValueGraphData {
export const AssetValueGraph = (props: {
label: string;
width: string;
height?: number;
yAxisLabel?: string;
data: AssetValueGraphData;
xHover: string | number | null;
Expand Down Expand Up @@ -167,5 +168,12 @@ export const AssetValueGraph = (props: {
},
};

return <Line data={graphData} height={100} options={options as any} key={props.width} />;
return (
<Line
data={graphData}
height={props.height || 100}
options={options as any}
key={props.width}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {DeletionDialog} from './DeletionDialog';
import {ReexecutionDialog} from './ReexecutionDialog';
import {RunConfigDialog} from './RunConfigDialog';
import {doneStatuses, failedStatuses} from './RunStatuses';
import {DagsterTag} from './RunTag';
import {RunTags} from './RunTags';
import {RunsQueryRefetchContext} from './RunUtils';
import {RunFilterToken} from './RunsFilterInput';
Expand All @@ -36,6 +37,7 @@ import {useJobAvailabilityErrorForRun} from './useJobAvailabilityErrorForRun';
import {useJobReexecution} from './useJobReExecution';
import {AppContext} from '../app/AppContext';
import {showSharedToaster} from '../app/DomUtils';
import {InjectedComponentContext} from '../app/InjectedComponentContext';
import {DEFAULT_DISABLED_REASON} from '../app/Permissions';
import {useCopyToClipboard} from '../app/browser';
import {ReexecutionStrategy} from '../graphql/types';
Expand All @@ -53,9 +55,10 @@ interface Props {
}

export const RunActionsMenu = React.memo(({run, onAddTag, additionalActionsForRun}: Props) => {
const {RunMetricsDialog} = React.useContext(InjectedComponentContext);
const {refetch} = React.useContext(RunsQueryRefetchContext);
const [visibleDialog, setVisibleDialog] = React.useState<
'none' | 'terminate' | 'delete' | 'config' | 'tags'
'none' | 'terminate' | 'delete' | 'config' | 'tags' | 'metrics'
>('none');

const {rootServerURI} = React.useContext(AppContext);
Expand Down Expand Up @@ -90,6 +93,7 @@ export const RunActionsMenu = React.memo(({run, onAddTag, additionalActionsForRu
const pipelineRun =
data?.pipelineRunOrError?.__typename === 'Run' ? data?.pipelineRunOrError : null;
const runConfigYaml = pipelineRun?.runConfigYaml;
const runMetricsEnabled = run.tags.some((t) => t.key === DagsterTag.RunMetrics);

const repoMatch = useRepositoryForRunWithParentSnapshot(pipelineRun);
const jobError = useJobAvailabilityErrorForRun({
Expand Down Expand Up @@ -218,6 +222,16 @@ export const RunActionsMenu = React.memo(({run, onAddTag, additionalActionsForRu
download
href={`${rootServerURI}/download_debug/${run.id}`}
/>
{RunMetricsDialog ? (
<MenuItem
tagName="button"
icon="asset_plot"
text="View container metrics"
intent="none"
disabled={!runMetricsEnabled}
onClick={() => setVisibleDialog('metrics')}
/>
) : null}
{run.hasDeletePermission ? (
<MenuItem
tagName="button"
Expand Down Expand Up @@ -247,6 +261,13 @@ export const RunActionsMenu = React.memo(({run, onAddTag, additionalActionsForRu
selectedRuns={{[run.id]: run.canTerminate}}
/>
) : null}
{runMetricsEnabled && RunMetricsDialog ? (
<RunMetricsDialog
runId={run.id}
isOpen={visibleDialog === 'metrics'}
onClose={closeDialogs}
/>
) : null}
{run.hasDeletePermission ? (
<DeletionDialog
isOpen={visibleDialog === 'delete'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import {useHistory} from 'react-router-dom';
import {DeletionDialog} from './DeletionDialog';
import {RunConfigDialog} from './RunConfigDialog';
import {doneStatuses} from './RunStatuses';
import {DagsterTag} from './RunTag';
import {RunsQueryRefetchContext} from './RunUtils';
import {TerminationDialog} from './TerminationDialog';
import {RunFragment} from './types/RunFragments.types';
import {AppContext} from '../app/AppContext';
import {showSharedToaster} from '../app/DomUtils';
import {InjectedComponentContext} from '../app/InjectedComponentContext';
import {useCopyToClipboard} from '../app/browser';
import {FREE_CONCURRENCY_SLOTS_MUTATION} from '../instance/InstanceConcurrency';
import {
Expand All @@ -20,14 +22,17 @@ import {
import {AnchorButton} from '../ui/AnchorButton';
import {workspacePipelineLinkForRun, workspacePipelinePath} from '../workspace/workspacePath';

type VisibleDialog = 'config' | 'delete' | 'terminate' | 'free_slots' | null;
type VisibleDialog = 'config' | 'delete' | 'terminate' | 'free_slots' | 'metrics' | null;

export const RunHeaderActions = ({run, isJob}: {run: RunFragment; isJob: boolean}) => {
const {runConfigYaml} = run;
const runMetricsEnabled = run.tags.some((t) => t.key === DagsterTag.RunMetrics);

const [visibleDialog, setVisibleDialog] = useState<VisibleDialog>(null);

const {rootServerURI} = useContext(AppContext);
const {refetch} = useContext(RunsQueryRefetchContext);
const {RunMetricsDialog} = useContext(InjectedComponentContext);

const copy = useCopyToClipboard();
const history = useHistory();
Expand Down Expand Up @@ -96,6 +101,16 @@ export const RunHeaderActions = ({run, isJob}: {run: RunFragment; isJob: boolean
onClick={() => window.open(`${rootServerURI}/download_debug/${run.id}`)}
/>
</Tooltip>
{RunMetricsDialog ? (
<MenuItem
tagName="button"
icon="asset_plot"
text="View container metrics"
intent="none"
disabled={!runMetricsEnabled}
onClick={() => setVisibleDialog('metrics')}
/>
) : null}
{run.hasConcurrencyKeySlots && doneStatuses.has(run.status) ? (
<MenuItem
text="Free concurrency slots"
Expand Down Expand Up @@ -126,6 +141,13 @@ export const RunHeaderActions = ({run, isJob}: {run: RunFragment; isJob: boolean
tags={run.tags}
isJob={isJob}
/>
{runMetricsEnabled && RunMetricsDialog ? (
<RunMetricsDialog
runId={run.id}
isOpen={visibleDialog === 'metrics'}
onClose={() => setVisibleDialog(null)}
/>
) : null}
{run.hasDeletePermission ? (
<DeletionDialog
isOpen={visibleDialog === 'delete'}
Expand Down
1 change: 1 addition & 0 deletions js_modules/dagster-ui/packages/ui-core/src/runs/RunTag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export enum DagsterTag {
SnapshotID = 'dagster/snapshot_id', // This only exists on the client, not the server.
ReportingUser = 'dagster/reporting_user',
User = 'user',
RunMetrics = 'dagster/run_metrics',

// Hidden tags (using ".dagster" HIDDEN_TAG_PREFIX)
RepositoryLabelTag = '.dagster/repository',
Expand Down

1 comment on commit 800b579

@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-bpug54xmu-elementl.vercel.app

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

Please sign in to comment.