Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: rerun task action in execution page #488

Merged
merged 8 commits into from
May 26, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Button } from '@material-ui/core';
import * as React from 'react';
import { ResourceIdentifier } from 'models/Common/types';
import { LaunchFormDialog } from 'components/Launch/LaunchForm/LaunchFormDialog';
import { NodeExecutionDetails } from '../types';
import t from './strings';

export const ExecutionDetailsActions: React.FC<{
className?: string;
details: NodeExecutionDetails;
}> = ({ className, details }) => {
const [showLaunchForm, setShowLaunchForm] = React.useState<boolean>(false);

const id = details.taskTemplate?.id as ResourceIdentifier | undefined;
anrusina marked this conversation as resolved.
Show resolved Hide resolved

const rerunOnClick = (e: React.MouseEvent<HTMLElement>) => {
e.stopPropagation();
setShowLaunchForm(true);
};

return (
<>
<div className={className}>
<Button variant="outlined" color="primary" onClick={rerunOnClick}>
{t('rerun')}
</Button>
</div>
{id && (
<LaunchFormDialog
id={id}
showLaunchForm={showLaunchForm}
setShowLaunchForm={setShowLaunchForm}
/>
)}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { getTaskExecutionDetailReasons } from './utils';
import { ExpandableMonospaceText } from '../../common/ExpandableMonospaceText';
import { fetchWorkflowExecution } from '../useWorkflowExecution';
import { NodeExecutionTabs } from './NodeExecutionTabs';
import { ExecutionDetailsActions } from './ExecutionDetailsActions';

const useStyles = makeStyles((theme: Theme) => {
const paddingVertical = `${theme.spacing(2)}px`;
Expand Down Expand Up @@ -93,6 +94,11 @@ const useStyles = makeStyles((theme: Theme) => {
marginTop: theme.spacing(2),
paddingTop: theme.spacing(2),
},
actionsContainer: {
borderTop: `1px solid ${theme.palette.divider}`,
marginTop: theme.spacing(2),
paddingTop: theme.spacing(2),
},
nodeTypeContent: {
minWidth: theme.spacing(9),
},
Expand Down Expand Up @@ -395,6 +401,9 @@ export const NodeExecutionDetailsPanelContent: React.FC<NodeExecutionDetailsProp
</Typography>
{statusContent}
{!dag && detailsContent}
{details && (
<ExecutionDetailsActions className={styles.actionsContainer} details={details} />
)}
</div>
</header>
{dag ? <WorkflowTabs nodeId={nodeExecutionId.nodeId} dagData={dag} /> : tabsContent}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createLocalizedString } from '@flyteconsole/locale';

const str = {
rerun: 'RERUN',
};

export { patternKey } from '@flyteconsole/locale';
export default createLocalizedString(str);
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { IconButton } from '@material-ui/core';
import { NodeExecution } from 'models/Execution/types';
import * as React from 'react';
import InputsAndOutputsIcon from '@material-ui/icons/Tv';
import RerunIcon from '@material-ui/icons/Autorenew';
import { ResourceIdentifier } from 'models/Common/types';
import { LaunchFormDialog } from 'components/Launch/LaunchForm/LaunchFormDialog';
import { NodeExecutionsTableState } from './types';
import { useNodeExecutionContext } from '../contextProvider/NodeExecutionDetails';
import { NodeExecutionDetails } from '../types';

export const NodeExecutionActions: React.FC<{
className?: string;
anrusina marked this conversation as resolved.
Show resolved Hide resolved
execution: NodeExecution;
state: NodeExecutionsTableState;
}> = ({ className, execution, state }) => {
const detailsContext = useNodeExecutionContext();
const [showLaunchForm, setShowLaunchForm] = React.useState<boolean>(false);
const [nodeExecutionDetails, setNodeExecutionDetails] = React.useState<
NodeExecutionDetails | undefined
>();

// open the side panel for selected execution's detail
const inputsAndOutputsIconOnClick = (e: React.MouseEvent<HTMLElement>) => {
// prevent the parent row body onClick event trigger
e.stopPropagation();
// use null in case if there is no execution provided - when it is null will close panel
state.setSelectedExecution(execution?.id ?? null);
};

const rerunIconOnClick = (e: React.MouseEvent<HTMLElement>) => {
e.stopPropagation();
setShowLaunchForm(true);
};

React.useEffect(() => {
detailsContext.getNodeExecutionDetails(execution).then((res) => {
setNodeExecutionDetails(res);
});
});

const id = nodeExecutionDetails?.taskTemplate?.id as ResourceIdentifier | undefined;

return (
<>
<div>
<IconButton onClick={inputsAndOutputsIconOnClick}>
<InputsAndOutputsIcon />
</IconButton>
<IconButton onClick={rerunIconOnClick}>
<RerunIcon />
</IconButton>
</div>
{id && (
<LaunchFormDialog
id={id}
showLaunchForm={showLaunchForm}
setShowLaunchForm={setShowLaunchForm}
/>
)}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useNodeExecutionContext } from '../contextProvider/NodeExecutionDetails
import { ExecutionStatusBadge } from '../ExecutionStatusBadge';
import { NodeExecutionCacheStatus } from '../NodeExecutionCacheStatus';
import { getNodeExecutionTimingMS } from '../utils';
import { NodeExecutionActions } from './NodeExecutionActions';
import { SelectNodeExecutionLink } from './SelectNodeExecutionLink';
import { useColumnStyles } from './styles';
import { NodeExecutionCellRendererData, NodeExecutionColumnDefinition } from './types';
Expand Down Expand Up @@ -201,11 +202,11 @@ export function generateColumns(
},
{
cellRenderer: ({ execution, state }) => (
<SelectNodeExecutionLink execution={execution} linkText="View Logs" state={state} />
<NodeExecutionActions execution={execution} state={state} />
),
className: styles.columnLogs,
key: 'logs',
label: 'logs',
key: 'actions',
label: '',
},
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Dialog } from '@material-ui/core';
import * as React from 'react';
import { LaunchForm } from 'components/Launch/LaunchForm/LaunchForm';
import { ResourceIdentifier, ResourceType } from 'models/Common/types';

function getLaunchProps(id: ResourceIdentifier) {
if (id.resourceType === ResourceType.TASK) {
return { taskId: id };
}

return { workflowId: id };
anrusina marked this conversation as resolved.
Show resolved Hide resolved
}

export const LaunchFormDialog: React.FC<{
className?: string;
anrusina marked this conversation as resolved.
Show resolved Hide resolved
id: ResourceIdentifier;
showLaunchForm: boolean;
setShowLaunchForm: React.Dispatch<React.SetStateAction<boolean>>;
}> = ({ className, id, showLaunchForm, setShowLaunchForm }) => {
const onCancelLaunch = () => setShowLaunchForm(false);

// prevent child onclick event in the dialog triggers parent onclick event
const dialogOnClick = (e: React.MouseEvent<HTMLElement>) => {
e.stopPropagation();
};

return (
<Dialog
scroll="paper"
maxWidth="sm"
fullWidth={true}
open={showLaunchForm}
onClick={dialogOnClick}
>
<LaunchForm onClose={onCancelLaunch} {...getLaunchProps(id)} />
</Dialog>
);
};