import { PropertyValue } from "~/models/search-bar";
-export const formatDate = (isoDate?: string) => {
+export const formatDate = (isoDate?: string | null) => {
if (isoDate) {
const date = new Date(isoDate);
const text = date.toLocaleString();
lowercaseValue?: boolean;
link?: string;
children?: React.ReactNode;
+ onValueClick?: () => void;
}
type DetailsAttributeProps = DetailsAttributeDataProps & WithStyles<CssRules>;
export const DetailsAttribute = withStyles(styles)(
- ({ label, link, value, children, classes, classLabel, classValue, lowercaseValue }: DetailsAttributeProps) =>
+ ({ label, link, value, children, classes, classLabel, classValue, lowercaseValue, onValueClick }: DetailsAttributeProps) =>
<Typography component="div" className={classes.attribute}>
<Typography component="span" className={classnames([classes.label, classLabel])}>{label}</Typography>
{ link
? <a href={link} className={classes.link} target='_blank'>{value}</a>
- : <Typography component="span" className={classnames([classes.value, classValue, { [classes.lowercaseValue]: lowercaseValue }])}>
+ : <Typography
+ onClick={onValueClick}
+ component="span"
+ className={classnames([classes.value, classValue, { [classes.lowercaseValue]: lowercaseValue }])}
+ >
{value}
{children}
</Typography> }
import { ProcessStatus } from '~/store/processes/process';
import { RootState } from '~/store/store';
import { ServiceRepository } from "~/services/services";
-import { navigateToCollection } from '~/store/navigation/navigation-action';
+import { navigateToCollection, navigateToWorkflows } from '~/store/navigation/navigation-action';
import { snackbarActions } from '~/store/snackbar/snackbar-actions';
import { SnackbarKind } from '../snackbar/snackbar-actions';
+import { showWorkflowDetails } from '~/store/workflow-panel/workflow-panel-actions';
export const procesPanelActions = unionize({
SET_PROCESS_PANEL_FILTERS: ofType<string[]>(),
}
};
+export const openWorkflow = (uuid: string) =>
+ (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ dispatch<any>(navigateToWorkflows);
+ dispatch<any>(showWorkflowDetails(uuid));
+ };
+
export const initProcessPanelFilters = procesPanelActions.SET_PROCESS_PANEL_FILTERS([
ProcessStatus.QUEUED,
ProcessStatus.COMPLETED,
import { Process } from '~/store/processes/process';
import { getProcessStatus, getProcessStatusColor } from '~/store/processes/process';
import { formatDate } from '~/common/formatters';
-
+import { openWorkflow } from "~/store/process-panel/process-panel-actions";
type CssRules = 'card' | 'iconHeader' | 'label' | 'value' | 'chip' | 'link' | 'content' | 'title' | 'avatar';
onContextMenu: (event: React.MouseEvent<HTMLElement>) => void;
openProcessInputDialog: (uuid: string) => void;
navigateToOutput: (uuid: string) => void;
+ navigateToWorkflow: (uuid: string) => void;
}
type ProcessInformationCardProps = ProcessInformationCardDataProps & WithStyles<CssRules, true>;
export const ProcessInformationCard = withStyles(styles, { withTheme: true })(
- ({ classes, process, onContextMenu, theme, openProcessInputDialog, navigateToOutput }: ProcessInformationCardProps) =>
- <Card className={classes.card}>
+ ({ classes, process, onContextMenu, theme, openProcessInputDialog, navigateToOutput, navigateToWorkflow }: ProcessInformationCardProps) => {
+ const { container } = process;
+ const startedAt = container ? formatDate(container.startedAt) : 'N/A';
+ const finishedAt = container ? formatDate(container.finishedAt) : 'N/A';
+ return <Card className={classes.card}>
<CardHeader
classes={{
content: classes.title,
avatar: classes.avatar
}}
- avatar={<ProcessIcon className={classes.iconHeader} />}
+ avatar={<ProcessIcon className={classes.iconHeader}/>}
action={
<div>
<Chip label={getProcessStatus(process)}
- className={classes.chip}
- style={{ backgroundColor: getProcessStatusColor(getProcessStatus(process), theme as ArvadosTheme) }} />
+ className={classes.chip}
+ style={{backgroundColor: getProcessStatusColor(getProcessStatus(process), theme as ArvadosTheme)}}/>
<Tooltip title="More options" disableFocusListener>
<IconButton
aria-label="More options"
onClick={event => onContextMenu(event)}>
- <MoreOptionsIcon />
+ <MoreOptionsIcon/>
</IconButton>
</Tooltip>
</div>
<Typography noWrap variant="body2" color='inherit'>
{getDescription(process)}
</Typography>
- </Tooltip>} />
+ </Tooltip>}/>
<CardContent className={classes.content}>
<Grid container>
<Grid item xs={6}>
<DetailsAttribute classLabel={classes.label} classValue={classes.value}
- label='From' value={process.container ? formatDate(process.container.startedAt!) : 'N/A'} />
+ label='From'
+ value={process.container ? formatDate(startedAt) : 'N/A'}/>
<DetailsAttribute classLabel={classes.label} classValue={classes.value}
- label='To' value={process.container ? formatDate(process.container.finishedAt!) : 'N/A'} />
- <DetailsAttribute classLabel={classes.label} classValue={classes.link}
- label='Workflow' value='???' />
+ label='To'
+ value={process.container ? formatDate(finishedAt) : 'N/A'}/>
+ {process.containerRequest.properties.templateUuid &&
+ <DetailsAttribute label='Workflow' classLabel={classes.label} classValue={classes.link}
+ value={process.containerRequest.properties.templateUuid}
+ onValueClick={() => navigateToWorkflow(process.containerRequest.properties.templateUuid)}
+ />}
</Grid>
<Grid item xs={6}>
<span onClick={() => navigateToOutput(process.containerRequest.outputUuid!)}>
- <DetailsAttribute classLabel={classes.link} label='Outputs' />
+ <DetailsAttribute classLabel={classes.link} label='Outputs'/>
</span>
<span onClick={() => openProcessInputDialog(process.containerRequest.uuid)}>
- <DetailsAttribute classLabel={classes.link} label='Inputs' />
+ <DetailsAttribute classLabel={classes.link} label='Inputs'/>
</span>
</Grid>
</Grid>
</CardContent>
- </Card>
+ </Card>;
+ }
);
const getDescription = (process: Process) =>
onToggle: (status: string) => void;
openProcessInputDialog: (uuid: string) => void;
navigateToOutput: (uuid: string) => void;
+ navigateToWorkflow: (uuid: string) => void;
}
export type ProcessPanelRootProps = ProcessPanelRootDataProps & ProcessPanelRootActionProps;
process={process}
onContextMenu={event => props.onContextMenu(event, process)}
openProcessInputDialog={props.openProcessInputDialog}
- navigateToOutput={props.navigateToOutput} />
+ navigateToOutput={props.navigateToOutput}
+ navigateToWorkflow={props.navigateToWorkflow}
+ />
</Grid>
<Grid item sm={12} md={5}>
<SubprocessesCard
import { ProcessPanelRootDataProps, ProcessPanelRootActionProps, ProcessPanelRoot } from './process-panel-root';
import { ProcessPanel as ProcessPanelState} from '~/store/process-panel/process-panel';
import { groupBy } from 'lodash';
-import { toggleProcessPanelFilter, navigateToOutput } from '~/store/process-panel/process-panel-actions';
+import { toggleProcessPanelFilter, navigateToOutput, openWorkflow } from '~/store/process-panel/process-panel-actions';
import { openProcessInputDialog } from '~/store/processes/process-input-actions';
const mapStateToProps = ({ router, resources, processPanel }: RootState): ProcessPanelRootDataProps => {
dispatch<any>(toggleProcessPanelFilter(status));
},
openProcessInputDialog: (uuid) => dispatch<any>(openProcessInputDialog(uuid)),
- navigateToOutput: (uuid) => dispatch<any>(navigateToOutput(uuid))
+ navigateToOutput: (uuid) => dispatch<any>(navigateToOutput(uuid)),
+ navigateToWorkflow: (uuid) => dispatch<any>(openWorkflow(uuid))
});
export const ProcessPanel = connect(mapStateToProps, mapDispatchToProps)(ProcessPanelRoot);