Skip to content

Commit

Permalink
[dagit] Modify "Open in Launchpad" from Run (#7263)
Browse files Browse the repository at this point in the history
  • Loading branch information
hellendag committed Apr 1, 2022
1 parent c997aa3 commit 5c7ec2e
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import {gql, useQuery} from '@apollo/client';
import * as React from 'react';
import {Redirect, useParams} from 'react-router-dom';

import {
IExecutionSession,
applyCreateSession,
useExecutionSessionStorage,
} from '../app/ExecutionSessionStorage';
import {usePermissions} from '../app/Permissions';
import {PYTHON_ERROR_FRAGMENT} from '../app/PythonErrorInfo';
import {explorerPathFromString} from '../pipelines/PipelinePathUtils';
import {useJobTitle} from '../pipelines/useJobTitle';
import {isThisThingAJob, useRepository} from '../workspace/WorkspaceContext';
import {RepoAddress} from '../workspace/types';
import {workspacePathFromAddress} from '../workspace/workspacePath';

import {LaunchpadSessionError} from './LaunchpadSessionError';
import {LaunchpadSessionLoading} from './LaunchpadSessionLoading';
import {ConfigForRunQuery} from './types/ConfigForRunQuery';

export const LaunchpadSetupFromRunRoot: React.FC<{repoAddress: RepoAddress}> = (props) => {
const {repoAddress} = props;
const {canLaunchPipelineExecution} = usePermissions();
const {repoPath, pipelinePath, runId} = useParams<{
repoPath: string;
pipelinePath: string;
runId: string;
}>();

if (!canLaunchPipelineExecution) {
return <Redirect to={`/workspace/${repoPath}/pipeline_or_job/${pipelinePath}`} />;
}
return (
<LaunchpadSetupFromRunAllowedRoot
pipelinePath={pipelinePath}
repoAddress={repoAddress}
runId={runId}
/>
);
};

interface Props {
pipelinePath: string;
repoAddress: RepoAddress;
runId: string;
}

/**
* For a given run ID, retrieve the run config and populate a new Launchpad session with its
* values, then redirect to the launchpad. The newly created session will be the open launchpad
* config tab.
*/
const LaunchpadSetupFromRunAllowedRoot: React.FC<Props> = (props) => {
const {pipelinePath, repoAddress, runId} = props;

const explorerPath = explorerPathFromString(pipelinePath);
const {pipelineName} = explorerPath;

const repo = useRepository(repoAddress);
const isJob = isThisThingAJob(repo, pipelineName);

useJobTitle(explorerPath, isJob);

const [storageData, onSave] = useExecutionSessionStorage(repoAddress.name, pipelineName);

const {data, loading} = useQuery<ConfigForRunQuery>(CONFIG_FOR_RUN_QUERY, {variables: {runId}});
const runOrError = data?.runOrError;
const run = runOrError?.__typename === 'Run' ? runOrError : null;

React.useEffect(() => {
// Wait until we have a run, then create the session.
if (!run) {
return;
}

const {runConfigYaml, mode, solidSelection} = run;
if (runConfigYaml || mode || solidSelection) {
// Name the session after this run ID.
const newSession: Partial<IExecutionSession> = {name: `From run ${run.id.slice(0, 8)}`};

if (typeof runConfigYaml === 'string') {
newSession.runConfigYaml = runConfigYaml;
}
if (typeof mode === 'string') {
newSession.mode = mode;
}
if (solidSelection instanceof Array && solidSelection.length > 0) {
newSession.solidSelection = solidSelection as string[];
} else if (typeof solidSelection === 'string' && solidSelection) {
newSession.solidSelection = [solidSelection];
}

onSave(applyCreateSession(storageData, newSession));
}
}, [run, storageData, onSave]);

if (loading) {
return <LaunchpadSessionLoading />;
}

if (!runOrError || runOrError.__typename === 'RunNotFoundError') {
return (
<LaunchpadSessionError
icon="error"
title="No run found"
description="The run with this ID does not exist or has been cleaned up."
/>
);
}

if (runOrError.__typename === 'PythonError') {
return (
<LaunchpadSessionError icon="error" title="Python error" description={runOrError.message} />
);
}

return (
<Redirect
to={{
pathname: workspacePathFromAddress(
repoAddress,
`/${isJob ? 'jobs' : 'pipelines'}/${pipelineName}/playground`,
),
}}
/>
);
};

const CONFIG_FOR_RUN_QUERY = gql`
query ConfigForRunQuery($runId: ID!) {
runOrError(runId: $runId) {
... on Run {
id
mode
runConfigYaml
solidSelection
}
...PythonErrorFragment
}
}
${PYTHON_ERROR_FRAGMENT}
`;

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

9 changes: 9 additions & 0 deletions js_modules/dagit/packages/core/src/pipelines/PipelineRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import {Redirect, Route, RouteComponentProps, Switch} from 'react-router-dom';

import {LaunchpadRoot} from '../launchpad/LaunchpadRoot';
import {LaunchpadSetupFromRunRoot} from '../launchpad/LaunchpadSetupFromRunRoot';
import {LaunchpadSetupRoot} from '../launchpad/LaunchpadSetupRoot';
import {PipelineNav} from '../nav/PipelineNav';
import {PipelinePartitionsRoot} from '../partitions/PipelinePartitionsRoot';
Expand Down Expand Up @@ -41,6 +42,14 @@ export const PipelineRoot: React.FC<Props> = (props) => {
>
<LaunchpadSetupRoot repoAddress={repoAddress} />
</Route>
<Route
path={[
'/workspace/:repoPath/pipelines/:pipelinePath/playground/setup-from-run/:runId',
'/workspace/:repoPath/jobs/:pipelinePath/playground/setup-from-run/:runId',
]}
>
<LaunchpadSetupFromRunRoot repoAddress={repoAddress} />
</Route>
<Route
path={[
'/workspace/:repoPath/pipelines/:pipelinePath/playground',
Expand Down
6 changes: 1 addition & 5 deletions js_modules/dagit/packages/core/src/runs/RunActionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
Popover,
Tooltip,
} from '@dagster-io/ui';
import qs from 'qs';
import * as React from 'react';
import {useHistory} from 'react-router-dom';
import * as yaml from 'yaml';
Expand Down Expand Up @@ -75,10 +74,7 @@ export const RunActionsMenu: React.FC<{
const isJob = !!(repoMatch && isThisThingAJob(repoMatch?.match, run.pipelineName));

const launchpadPath = () => {
const path = `/playground/setup?${qs.stringify({
config: runConfigYaml,
solidSelection: run.solidSelection,
})}`;
const path = `/playground/setup-from-run/${run.id}`;

if (repoMatch) {
return workspacePipelinePath({
Expand Down

0 comments on commit 5c7ec2e

Please sign in to comment.