return items;
};
+export const cancelRunningWorkflow = (uuid: string) =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ try {
+ const process = await services.containerRequestService.update(uuid, { priority: 0 });
+ return process;
+ } catch (e) {
+ throw new Error('Could not cancel the process.');
+ }
+ };
+
export const reRunProcess = (processUuid: string, workflowUuid: string) =>
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
const process = getResource<any>(processUuid)(getState().resources);
const basicInitialData: RunProcessBasicFormData = { name: `Copy of: ${process.name}`, description: process.description };
dispatch<any>(initialize(RUN_PROCESS_BASIC_FORM, basicInitialData));
- const advancedInitialData: RunProcessAdvancedFormData = {
- output: process.outputName,
- runtime: process.schedulingParameters.maxRunTime,
+ const advancedInitialData: RunProcessAdvancedFormData = {
+ output: process.outputName,
+ runtime: process.schedulingParameters.maxRunTime,
ram: process.runtimeConstraints.ram,
vcpus: process.runtimeConstraints.vcpus,
keepCacheRam: process.runtimeConstraints.keepCacheRam,
api: process.runtimeConstraints.API
- };
- dispatch<any>(initialize(RUN_PROCESS_ADVANCED_FORM, advancedInitialData));
+ };
+ dispatch<any>(initialize(RUN_PROCESS_ADVANCED_FORM, advancedInitialData));
dispatch<any>(navigateToRunProcess);
dispatch<any>(goToStep(1));
import { getProcessStatus, getProcessStatusColor } from '~/store/processes/process';
import { formatDate } from '~/common/formatters';
import * as classNames from 'classnames';
+import { ContainerState } from '~/models/container';
-type CssRules = 'card' | 'iconHeader' | 'label' | 'value' | 'chip' | 'link' | 'content' | 'title' | 'avatar';
+type CssRules = 'card' | 'iconHeader' | 'label' | 'value' | 'chip' | 'link' | 'content' | 'title' | 'avatar' | 'cancelButton';
const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
card: {
title: {
overflow: 'hidden',
paddingTop: theme.spacing.unit * 0.5
+ },
+ cancelButton: {
+ paddingRight: theme.spacing.unit * 2,
+ fontSize: '14px',
+ color: theme.customs.colors.red900,
+ "&:hover": {
+ cursor: 'pointer'
+ }
}
});
openProcessInputDialog: (uuid: string) => void;
navigateToOutput: (uuid: string) => void;
openWorkflow: (uuid: string) => void;
+ cancelProcess: (uuid: string) => void;
}
type ProcessInformationCardProps = ProcessInformationCardDataProps & WithStyles<CssRules, true>;
export const ProcessInformationCard = withStyles(styles, { withTheme: true })(
- ({ classes, process, onContextMenu, theme, openProcessInputDialog, navigateToOutput, openWorkflow }: ProcessInformationCardProps) => {
+ ({ classes, process, onContextMenu, theme, openProcessInputDialog, navigateToOutput, openWorkflow, cancelProcess }: ProcessInformationCardProps) => {
const { container } = process;
const startedAt = container ? formatDate(container.startedAt) : 'N/A';
const finishedAt = container ? formatDate(container.finishedAt) : 'N/A';
avatar={<ProcessIcon className={classes.iconHeader} />}
action={
<div>
+ {process.container && process.container.state === ContainerState.RUNNING &&
+ <span className={classes.cancelButton} onClick={() => cancelProcess(process.containerRequest.uuid)}>Cancel</span>}
<Chip label={getProcessStatus(process)}
className={classes.chip}
style={{ backgroundColor: getProcessStatusColor(getProcessStatus(process), theme as ArvadosTheme) }} />
value={process.container ? formatDate(finishedAt) : 'N/A'} />
{process.containerRequest.properties.workflowUuid &&
<span onClick={() => openWorkflow(process.containerRequest.properties.workflowUuid)}>
- <DetailsAttribute classLabel={classes.label} classValue={classNames(classes.value, classes.link)}
- label='Workflow' value={process.containerRequest.properties.workflowName}/>
+ <DetailsAttribute classLabel={classes.label} classValue={classNames(classes.value, classes.link)}
+ label='Workflow' value={process.containerRequest.properties.workflowName} />
</span>}
</Grid>
<Grid item xs={6}>
openProcessInputDialog: (uuid: string) => void;
navigateToOutput: (uuid: string) => void;
navigateToWorkflow: (uuid: string) => void;
+ cancelProcess: (uuid: string) => void;
}
export type ProcessPanelRootProps = ProcessPanelRootDataProps & ProcessPanelRootActionProps;
openProcessInputDialog={props.openProcessInputDialog}
navigateToOutput={props.navigateToOutput}
openWorkflow={props.navigateToWorkflow}
+ cancelProcess={props.cancelProcess}
/>
</Grid>
<Grid item sm={12} md={5}>
import { groupBy } from 'lodash';
import { toggleProcessPanelFilter, navigateToOutput, openWorkflow } from '~/store/process-panel/process-panel-actions';
import { openProcessInputDialog } from '~/store/processes/process-input-actions';
+import { cancelRunningWorkflow } from '~/store/processes/processes-actions';
const mapStateToProps = ({ router, resources, processPanel }: RootState): ProcessPanelRootDataProps => {
const pathname = router.location ? router.location.pathname : '';
},
openProcessInputDialog: (uuid) => dispatch<any>(openProcessInputDialog(uuid)),
navigateToOutput: (uuid) => dispatch<any>(navigateToOutput(uuid)),
- navigateToWorkflow: (uuid) => dispatch<any>(openWorkflow(uuid))
+ navigateToWorkflow: (uuid) => dispatch<any>(openWorkflow(uuid)),
+ cancelProcess: (uuid) => dispatch<any>(cancelRunningWorkflow(uuid))
});
export const ProcessPanel = connect(mapStateToProps, mapDispatchToProps)(ProcessPanelRoot);
color: theme.palette.common.white,
},
status: {
- paddingTop: theme.spacing.unit * 0.5,
+ paddingTop: theme.spacing.unit * 0.75,
color: theme.palette.common.white,
},
rightSideHeader: {