1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from 'react';
6 import { WorkflowIcon, StartIcon } from 'components/icon/icon';
8 WorkflowResource, parseWorkflowDefinition, getWorkflowInputs,
9 getWorkflowOutputs, getWorkflow
10 } from 'models/workflow';
11 import { DetailsData } from "./details-data";
12 import { DetailsAttribute } from 'components/details-attribute/details-attribute';
13 import { ResourceWithName } from 'views-components/data-explorer/renderers';
14 import { formatDate } from "common/formatters";
15 import { Grid } from '@material-ui/core';
16 import { withStyles, StyleRulesCallback, WithStyles, Button } from '@material-ui/core';
17 import { openRunProcess } from "store/workflow-panel/workflow-panel-actions";
18 import { Dispatch } from 'redux';
19 import { connect } from 'react-redux';
20 import { ArvadosTheme } from 'common/custom-theme';
21 import { ProcessIOParameter } from 'views/process-panel/process-io-card';
22 import { formatInputData, formatOutputData } from 'store/process-panel/process-panel-actions';
23 import { AuthState } from 'store/auth/auth-reducer';
24 import { RootState } from 'store/store';
25 import { getPropertyChip } from "views-components/resource-properties-form/property-chip";
27 export interface WorkflowDetailsCardDataProps {
28 workflow?: WorkflowResource;
31 export interface WorkflowDetailsCardActionProps {
32 onClick: (wf: WorkflowResource) => () => void;
35 const mapDispatchToProps = (dispatch: Dispatch) => ({
36 onClick: (wf: WorkflowResource) =>
37 () => wf && dispatch<any>(openRunProcess(wf.uuid, wf.ownerUuid, wf.name)),
40 type CssRules = 'runButton' | 'propertyTag';
42 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
44 backgroundColor: theme.customs.colors.green700,
46 backgroundColor: theme.customs.colors.green800,
50 padding: '2px 10px 2px 5px',
54 marginRight: theme.spacing.unit / 2,
55 marginBottom: theme.spacing.unit / 2
59 interface AuthStateDataProps {
63 export interface RegisteredWorkflowPanelDataProps {
64 item: WorkflowResource;
65 workflowCollection: string;
66 inputParams: ProcessIOParameter[];
67 outputParams: ProcessIOParameter[];
68 gitprops: { [key: string]: string; };
71 export const getRegisteredWorkflowPanelData = (item: WorkflowResource, auth: AuthState): RegisteredWorkflowPanelDataProps => {
72 let inputParams: ProcessIOParameter[] = [];
73 let outputParams: ProcessIOParameter[] = [];
74 let workflowCollection = "";
75 const gitprops: { [key: string]: string; } = {};
78 const wfdef = parseWorkflowDefinition(item);
81 const inputs = getWorkflowInputs(wfdef);
83 inputs.forEach(elm => {
84 if (elm.default !== undefined && elm.default !== null) {
85 elm.value = elm.default;
88 inputParams = formatInputData(inputs, auth);
91 const outputs = getWorkflowOutputs(wfdef);
93 outputParams = formatOutputData(outputs, {}, undefined, auth);
96 const wf = getWorkflow(wfdef);
98 const REGEX = /keep:([0-9a-f]{32}\+\d+)\/.*/;
100 const pdh = wf["steps"][0].run.match(REGEX);
102 workflowCollection = pdh[1];
107 for (const elm in wfdef) {
108 if (elm.startsWith("http://arvados.org/cwl#git")) {
109 gitprops[elm.substr(23)] = wfdef[elm]
114 return { item, workflowCollection, inputParams, outputParams, gitprops };
117 const mapStateToProps = (state: RootState): AuthStateDataProps => {
118 return { auth: state.auth };
121 export const WorkflowDetailsAttributes = connect(mapStateToProps, mapDispatchToProps)(
123 ({ workflow, onClick, auth, classes }: WorkflowDetailsCardDataProps & AuthStateDataProps & WorkflowDetailsCardActionProps & WithStyles<CssRules>) => {
128 const data = getRegisteredWorkflowPanelData(workflow, auth);
129 return <Grid container>
130 <Button onClick={workflow && onClick(workflow)} className={classes.runButton} variant='contained'
131 data-cy='workflow-details-panel-run-btn' color='primary' size='small'>
137 label={"Workflow UUID"}
138 linkToUuid={workflow?.uuid} />
142 label='Owner' linkToUuid={workflow?.ownerUuid}
143 uuidEnhancer={(uuid: string) => <ResourceWithName uuid={uuid} />} />
146 <DetailsAttribute label='Created at' value={formatDate(workflow?.createdAt)} />
149 <DetailsAttribute label='Last modified' value={formatDate(workflow?.modifiedAt)} />
151 <Grid item xs={12} data-cy="workflow-details-attributes-modifiedby-user">
153 label='Last modified by user' linkToUuid={workflow?.modifiedByUserUuid}
154 uuidEnhancer={(uuid: string) => <ResourceWithName uuid={uuid} />} />
156 <Grid item xs={12} md={12}>
157 <DetailsAttribute label='Properties' />
158 {Object.keys(data.gitprops).map(k =>
159 getPropertyChip(k, data.gitprops[k], undefined, classes.propertyTag))}
164 export class WorkflowDetails extends DetailsData<WorkflowResource> {
165 getIcon(className?: string) {
166 return <WorkflowIcon className={className} />;
170 return <WorkflowDetailsAttributes workflow={this.item} />;