1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from 'react';
6 import { CustomStyleRulesCallback } from 'common/custom-theme';
7 import { CardContent, Tab, Tabs, Table, TableHead, TableCell, TableBody, TableRow, Typography } from '@mui/material';
8 import { WithStyles } from '@mui/styles';
9 import withStyles from '@mui/styles/withStyles';
10 import { ArvadosTheme } from 'common/custom-theme';
11 import { WorkflowIcon } from 'components/icon/icon';
12 import { DataTableDefaultView } from 'components/data-table-default-view/data-table-default-view';
13 import { parseWorkflowDefinition, getWorkflowInputs, getInputLabel, stringifyInputType } from 'models/workflow';
14 import { WorkflowDetailsCardDataProps, WorkflowDetailsAttributes } from 'views-components/details-panel/workflow-details';
16 export type CssRules = 'root' | 'tab' | 'inputTab' | 'graphTab' | 'graphTabWithChosenWorkflow' | 'descriptionTab' | 'inputsTable' | 'workflowName';
18 const styles: CustomStyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
28 marginTop: theme.spacing(1)
31 marginTop: theme.spacing(1),
33 graphTabWithChosenWorkflow: {
36 marginTop: theme.spacing(1),
41 marginTop: theme.spacing(1),
51 type WorkflowDetailsCardProps = WorkflowDetailsCardDataProps & WithStyles<CssRules>;
53 export const WorkflowDetailsCard = withStyles(styles)(
54 class extends React.Component<WorkflowDetailsCardProps> {
59 handleChange = (event: React.MouseEvent<HTMLElement>, value: number) => {
60 this.setState({ value });
64 const { classes, workflow } = this.props;
65 const { value } = this.state;
66 return <div className={classes.root}>
67 <Typography className={classes.workflowName} variant='h6'>
68 {workflow && workflow.name}
70 <Tabs value={value} onChange={this.handleChange} centered={true}>
71 <Tab className={classes.tab} label="Description" />
72 <Tab className={classes.tab} label="Inputs" />
73 <Tab className={classes.tab} label="Details" />
75 {value === 0 && <CardContent className={classes.descriptionTab}>
76 {workflow ? <div dangerouslySetInnerHTML={{ __html: workflow.description || '(no-description)' }}></div> : (
79 messages={['Please select a workflow to see its description.']} />
82 {value === 1 && <CardContent className={classes.inputTab}>
84 ? this.renderInputsTable()
85 : <DataTableDefaultView
87 messages={['Please select a workflow to see its inputs.']} />
90 {value === 2 && <CardContent className={classes.descriptionTab}>
92 ? <WorkflowDetailsAttributes workflow={workflow} />
93 : <DataTableDefaultView
95 messages={['Please select a workflow to see its details.']} />
102 if (this.props.workflow) {
103 const definition = parseWorkflowDefinition(this.props.workflow);
105 return getWorkflowInputs(definition);
111 renderInputsTable() {
112 return <Table className={this.props.classes.inputsTable}>
115 <TableCell>Label</TableCell>
116 <TableCell>Type</TableCell>
117 <TableCell>Description</TableCell>
121 {this.inputs && this.inputs.map(input =>
122 <TableRow key={input.id}>
123 <TableCell>{getInputLabel(input)}</TableCell>
124 <TableCell>{stringifyInputType(input)}</TableCell>
125 <TableCell>{input.doc}</TableCell>