[ARVADOS-WORKBENCH2] created: 1.3.0-335-gf1db282d

Git user git at public.curoverse.com
Tue Jan 15 03:11:35 EST 2019


        at  f1db282d059c1d0a6e264943344e09bda5d40282 (commit)


commit f1db282d059c1d0a6e264943344e09bda5d40282
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date:   Tue Jan 15 09:11:20 2019 +0100

    re-run-workflow-and-display-workflow-inside-process-info-card
    
    Feature #14643
    
    Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>

diff --git a/package.json b/package.json
index 46b3ee4f..266ade27 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
     "@types/react-dnd": "3.0.2",
     "@types/react-dropzone": "4.2.2",
     "@types/react-highlight-words": "0.12.0",
-    "@types/redux-form": "7.4.12",
+    "@types/redux-form": "7.4.15",
     "@types/reselect": "2.2.0",
     "@types/shell-quote": "1.6.0",
     "axios": "0.18.0",
@@ -24,7 +24,7 @@
     "js-yaml": "3.12.0",
     "jssha": "2.3.1",
     "lodash": "4.17.11",
-    "react": "16.5.2",
+    "react": "16.7.0",
     "react-copy-to-clipboard": "5.0.1",
     "react-dnd": "5.0.0",
     "react-dnd-html5-backend": "5.0.1",
@@ -52,7 +52,7 @@
     "build": "REACT_APP_BUILD_NUMBER=$BUILD_NUMBER REACT_APP_GIT_COMMIT=$GIT_COMMIT react-scripts-ts build",
     "build-local": "react-scripts-ts build",
     "test": "CI=true react-scripts-ts test --env=jsdom",
-    "test-local": "react-scripts-ts test --env=jsdom",
+    "test-local": "react-scripts-ts test --env=jsdom --watchAll=false",
     "eject": "react-scripts-ts eject",
     "lint": "tslint src/** -t verbose",
     "build-css": "node-sass-chokidar src/ -o src/",
@@ -64,8 +64,8 @@
     "@types/enzyme-adapter-react-16": "1.0.3",
     "@types/jest": "23.3.3",
     "@types/node": "10.11.2",
-    "@types/react": "16.4",
-    "@types/react-dom": "16.0.8",
+    "@types/react": "16.7.18",
+    "@types/react-dom": "16.0.11",
     "@types/react-redux": "6.0.9",
     "@types/react-router": "4.0.31",
     "@types/react-router-dom": "4.3.1",
diff --git a/src/components/code-snippet/code-snippet.tsx b/src/components/code-snippet/code-snippet.tsx
index 6cba299f..a23a5fe2 100644
--- a/src/components/code-snippet/code-snippet.tsx
+++ b/src/components/code-snippet/code-snippet.tsx
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { StyleRulesCallback, WithStyles, Typography, withStyles, Theme } from '@material-ui/core';
+import { StyleRulesCallback, WithStyles, Typography, withStyles } from '@material-ui/core';
 import { ArvadosTheme } from '~/common/custom-theme';
 import * as classNames from 'classnames';
 
diff --git a/src/components/collection-panel-files/collection-panel-files.tsx b/src/components/collection-panel-files/collection-panel-files.tsx
index 581c3a76..028dfb0c 100644
--- a/src/components/collection-panel-files/collection-panel-files.tsx
+++ b/src/components/collection-panel-files/collection-panel-files.tsx
@@ -3,11 +3,11 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { TreeItem, TreeItemStatus } from '../tree/tree';
-import { FileTreeData } from '../file-tree/file-tree-data';
-import { FileTree } from '../file-tree/file-tree';
+import { TreeItem, TreeItemStatus } from '~/components/tree/tree';
+import { FileTreeData } from '~/components/file-tree/file-tree-data';
+import { FileTree } from '~/components/file-tree/file-tree';
 import { IconButton, Grid, Typography, StyleRulesCallback, withStyles, WithStyles, CardHeader, Card, Button, Tooltip } from '@material-ui/core';
-import { CustomizeTableIcon } from '../icon/icon';
+import { CustomizeTableIcon } from '~/components/icon/icon';
 import { DownloadIcon } from '~/components/icon/icon';
 
 export interface CollectionPanelFilesProps {
diff --git a/src/components/tree/tree.tsx b/src/components/tree/tree.tsx
index c64a7221..5b070b70 100644
--- a/src/components/tree/tree.tsx
+++ b/src/components/tree/tree.tsx
@@ -107,7 +107,7 @@ export const Tree = withStyles(styles)(
 
             const { levelIndentation = 20, itemRightPadding = 20 } = this.props;
 
-            return <List component="div" className={list}>
+            return <List className={list}>
                 {items && items.map((it: TreeItem<T>, idx: number) =>
                     <div key={`item/${level}/${idx}`}>
                         <ListItem button className={listItem} 
diff --git a/src/models/workflow.ts b/src/models/workflow.ts
index 3a38348e..a858c0d7 100644
--- a/src/models/workflow.ts
+++ b/src/models/workflow.ts
@@ -13,7 +13,8 @@ export interface WorkflowResource extends Resource {
 }
 export interface WorkflowResoruceDefinition {
     cwlVersion: string;
-    $graph: Array<Workflow | CommandLineTool>;
+    graph?: Array<Workflow | CommandLineTool>;
+    $graph?: Array<Workflow | CommandLineTool>;
 }
 export interface Workflow {
     class: 'Workflow';
@@ -122,11 +123,19 @@ export const parseWorkflowDefinition = (workflow: WorkflowResource): WorkflowRes
 };
 
 export const getWorkflowInputs = (workflowDefinition: WorkflowResoruceDefinition) => {
-    const mainWorkflow = workflowDefinition.$graph.find(item => item.class === 'Workflow' && item.id === '#main');
-    return mainWorkflow
-        ? mainWorkflow.inputs
-        : undefined;
+    if (workflowDefinition.graph) {
+        const mainWorkflow = workflowDefinition.graph.find(item => item.class === 'Workflow' && item.id === '#main');
+        return mainWorkflow
+            ? mainWorkflow.inputs
+            : undefined;
+    } else {
+        const mainWorkflow = workflowDefinition.$graph!.find(item => item.class === 'Workflow' && item.id === '#main');
+        return mainWorkflow
+            ? mainWorkflow.inputs
+            : undefined;
+    }
 };
+
 export const getInputLabel = (input: CommandInputParameter) => {
     return `${input.label || input.id}`;
 };
diff --git a/src/store/context-menu/context-menu-actions.ts b/src/store/context-menu/context-menu-actions.ts
index ca89f3eb..269495e5 100644
--- a/src/store/context-menu/context-menu-actions.ts
+++ b/src/store/context-menu/context-menu-actions.ts
@@ -36,6 +36,7 @@ export type ContextMenuResource = {
     menuKind: ContextMenuKind;
     isTrashed?: boolean;
     outputUuid?: string;
+    workflowUuid?: string;
 };
 
 export const isKeyboardClick = (event: React.MouseEvent<HTMLElement>) => event.nativeEvent.detail === 0;
@@ -187,6 +188,7 @@ export const openProcessContextMenu = (event: React.MouseEvent<HTMLElement>, pro
                 name: res.name,
                 description: res.description,
                 outputUuid: res.outputUuid || '',
+                workflowUuid: res.properties.workflowUuid || '',
                 menuKind: ContextMenuKind.PROCESS
             }));
         }
diff --git a/src/store/process-panel/process-panel-actions.ts b/src/store/process-panel/process-panel-actions.ts
index 42a718bd..f1f74f6d 100644
--- a/src/store/process-panel/process-panel-actions.ts
+++ b/src/store/process-panel/process-panel-actions.ts
@@ -26,6 +26,7 @@ export const loadProcessPanel = (uuid: string) =>
     (dispatch: Dispatch) => {
         dispatch<any>(loadProcess(uuid));
         dispatch(initProcessPanelFilters);
+        dispatch<any>(showWorkflowDetails(uuid));
     };
 
 export const navigateToOutput = (uuid: string) =>
@@ -41,7 +42,6 @@ export const navigateToOutput = (uuid: 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([
diff --git a/src/store/processes/process-input-actions.ts b/src/store/processes/process-input-actions.ts
index 98899a42..ab3f3bdb 100644
--- a/src/store/processes/process-input-actions.ts
+++ b/src/store/processes/process-input-actions.ts
@@ -15,7 +15,7 @@ export const openProcessInputDialog = (processUuid: string) =>
         const process = getProcess(processUuid)(getState().resources);
         if (process) {
             const data: any = process;
-            if (data && data.containerRequest.mounts.varLibCwlWorkflowJson && data.containerRequest.mounts.varLibCwlWorkflowJson.content.graph[1].inputs.length > 0) {
+            if (data && data.containerRequest.mounts.varLibCwlWorkflowJson && data.containerRequest.mounts.varLibCwlWorkflowJson.content.graph[1] && data.containerRequest.mounts.varLibCwlWorkflowJson.content.graph[1].inputs.length > 0) {
                 dispatch(dialogActions.OPEN_DIALOG({ id: PROCESS_INPUT_DIALOG_NAME, data }));
             } else {
                 dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'There are no inputs in this process!', kind: SnackbarKind.ERROR }));
diff --git a/src/store/processes/processes-actions.ts b/src/store/processes/processes-actions.ts
index fa81da9f..2c7b8cff 100644
--- a/src/store/processes/processes-actions.ts
+++ b/src/store/processes/processes-actions.ts
@@ -10,11 +10,20 @@ import { FilterBuilder } from '~/services/api/filter-builder';
 import { ContainerRequestResource } from '~/models/container-request';
 import { Process } from './process';
 import { dialogActions } from '~/store/dialog/dialog-actions';
-import {snackbarActions, SnackbarKind} from '~/store/snackbar/snackbar-actions';
+import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
 import { projectPanelActions } from '~/store/project-panel/project-panel-action';
+import { navigateToRunProcess } from '~/store/navigation/navigation-action';
+import { goToStep, runProcessPanelActions } from '~/store/run-process-panel/run-process-panel-actions';
+import { getResource } from '~/store/resources/resources';
+import { getInputValue } from "~/views-components/process-input-dialog/process-input-dialog";
+import { initialize } from "redux-form";
+import { RUN_PROCESS_BASIC_FORM, RunProcessBasicFormData } from "~/views/run-process-panel/run-process-basic-form";
+import { RunProcessAdvancedFormData, RUN_PROCESS_ADVANCED_FORM } from "~/views/run-process-panel/run-process-advanced-form";
 
 export const loadProcess = (containerRequestUuid: string) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<Process> => {
+        const response = await services.workflowService.list();
+        dispatch(runProcessPanelActions.SET_WORKFLOWS(response.items));
         const containerRequest = await services.containerRequestService.get(containerRequestUuid);
         dispatch<any>(updateResources([containerRequest]));
         if (containerRequest.containerUuid) {
@@ -58,6 +67,44 @@ export const loadContainers = (filters: string) =>
         return items;
     };
 
+export const reRunProcess = (processUuid: string, workflowUuid: string) =>
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+        const process = getResource<any>(processUuid)(getState().resources);
+        const workflows = getState().runProcessPanel.searchWorkflows;
+        const workflow = workflows.find(workflow => workflow.uuid === workflowUuid);
+        if (workflow && process) {
+            const newValues = getInputs(process);
+            process.mounts.varLibCwlWorkflowJson.content.graph[1].inputs = newValues;
+            const stringifiedDefinition = JSON.stringify(process.mounts.varLibCwlWorkflowJson.content);
+            const newWorkflow = { ...workflow, definition: stringifiedDefinition };
+
+            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, 
+                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>(navigateToRunProcess);
+            dispatch<any>(goToStep(1));
+            dispatch(runProcessPanelActions.SET_STEP_CHANGED(true));
+            dispatch(runProcessPanelActions.SET_SELECTED_WORKFLOW(newWorkflow));
+        } else {
+            dispatch<any>(snackbarActions.OPEN_SNACKBAR({ message: `You can't re-run this process`, kind: SnackbarKind.ERROR }));
+        }
+    };
+
+const getInputs = (data: any) =>
+    data && data.mounts.varLibCwlWorkflowJson ? data.mounts.varLibCwlWorkflowJson.content.graph[1].inputs.map((it: any) => (
+        { type: it.type, id: it.id, label: it.label, default: getInputValue(it.id, data.mounts.varLibCwlCwlInputJson.content), doc: it.doc }
+    )) : [];
+
 export const openRemoveProcessDialog = (uuid: string) =>
     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         dispatch(dialogActions.OPEN_DIALOG({
@@ -74,11 +121,11 @@ export const openRemoveProcessDialog = (uuid: string) =>
 export const REMOVE_PROCESS_DIALOG = 'removeProcessDialog';
 
 export const removeProcessPermanently = (uuid: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) =>{
+    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removing ...', kind: SnackbarKind.INFO }));
         await services.containerRequestService.delete(uuid);
         dispatch(projectPanelActions.REQUEST_ITEMS());
         dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removed.', hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
     };
-        
+
 
diff --git a/src/store/run-process-panel/run-process-panel-actions.ts b/src/store/run-process-panel/run-process-panel-actions.ts
index f7649860..12601729 100644
--- a/src/store/run-process-panel/run-process-panel-actions.ts
+++ b/src/store/run-process-panel/run-process-panel-actions.ts
@@ -149,6 +149,10 @@ export const runProcess = async (dispatch: Dispatch<any>, getState: () => RootSt
             outputPath: '/var/spool/cwl',
             priority: 1,
             outputName: advancedForm[OUTPUT_FIELD] ? advancedForm[OUTPUT_FIELD] : undefined,
+            properties: {
+                workflowUuid: selectedWorkflow.uuid,
+                workflowName: selectedWorkflow.name
+            }       
         };
         const newProcess = await services.containerRequestService.create(newProcessData);
         dispatch(navigateToProcess(newProcess.uuid));
diff --git a/src/store/workflow-panel/workflow-panel-actions.ts b/src/store/workflow-panel/workflow-panel-actions.ts
index 3d51cbb8..2f00bba6 100644
--- a/src/store/workflow-panel/workflow-panel-actions.ts
+++ b/src/store/workflow-panel/workflow-panel-actions.ts
@@ -7,11 +7,12 @@ import { RootState } from '~/store/store';
 import { ServiceRepository } from '~/services/services';
 import { bindDataExplorerActions } from '~/store/data-explorer/data-explorer-action';
 import { propertiesActions } from '~/store/properties/properties-actions';
-import { getResource } from '../resources/resources';
+import { getResource } from '~/store/resources/resources';
 import { getProperty } from '~/store/properties/properties';
 import { WorkflowResource } from '~/models/workflow';
 import { navigateToRunProcess } from '~/store/navigation/navigation-action';
 import { goToStep, runProcessPanelActions } from '~/store/run-process-panel/run-process-panel-actions';
+import { snackbarActions } from '~/store/snackbar/snackbar-actions';
 
 export const WORKFLOW_PANEL_ID = "workflowPanel";
 const UUID_PREFIX_PROPERTY_NAME = 'uuidPrefix';
@@ -33,14 +34,17 @@ export const getUuidPrefix = (state: RootState) => {
 };
 
 export const openRunProcess = (uuid: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {  
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         const workflows = getState().runProcessPanel.searchWorkflows;
         const workflow = workflows.find(workflow => workflow.uuid === uuid);
-        dispatch<any>(navigateToRunProcess);
-        dispatch(runProcessPanelActions.RESET_RUN_PROCESS_PANEL()); 
-        dispatch<any>(goToStep(1));
-        dispatch(runProcessPanelActions.SET_STEP_CHANGED(true));
-        dispatch(runProcessPanelActions.SET_SELECTED_WORKFLOW(workflow!));       
+        if (workflow) {
+            dispatch<any>(navigateToRunProcess);
+            dispatch<any>(goToStep(1));
+            dispatch(runProcessPanelActions.SET_STEP_CHANGED(true));
+            dispatch(runProcessPanelActions.SET_SELECTED_WORKFLOW(workflow));
+        } else {
+            dispatch<any>(snackbarActions.OPEN_SNACKBAR({ message: `You can't run this process` }));
+        }
     };
 
 export const getPublicUserUuid = (state: RootState) => {
diff --git a/src/views-components/context-menu/action-sets/process-action-set.ts b/src/views-components/context-menu/action-sets/process-action-set.ts
index 05242fbc..ed526968 100644
--- a/src/views-components/context-menu/action-sets/process-action-set.ts
+++ b/src/views-components/context-menu/action-sets/process-action-set.ts
@@ -19,8 +19,9 @@ import { openSharingDialog } from "~/store/sharing-dialog/sharing-dialog-actions
 import { openAdvancedTabDialog } from "~/store/advanced-tab/advanced-tab";
 import { openProcessInputDialog } from "~/store/processes/process-input-actions";
 import { toggleDetailsPanel } from '~/store/details-panel/details-panel-action';
-import { openRemoveProcessDialog } from "~/store/processes/processes-actions";
+import { openRemoveProcessDialog, reRunProcess } from "~/store/processes/processes-actions";
 import { navigateToOutput } from "~/store/process-panel/process-panel-actions";
+import { snackbarActions, SnackbarKind } from "~/store/snackbar/snackbar-actions";
 
 export const processActionSet: ContextMenuActionSet = [[
     {
@@ -63,8 +64,12 @@ export const processActionSet: ContextMenuActionSet = [[
         icon: ReRunProcessIcon,
         name: "Re-run process",
         execute: (dispatch, resource) => {
-            // add code
-        }
+            if(resource.workflowUuid) {
+                dispatch<any>(reRunProcess(resource.uuid, resource.workflowUuid));
+            } else {
+                dispatch(snackbarActions.OPEN_SNACKBAR({ message: `You can't re-run this process`, hideDuration: 2000, kind: SnackbarKind.ERROR }));
+            }        
+        }        
     },
     {
         icon: InputIcon,
diff --git a/src/views-components/process-input-dialog/process-input-dialog.tsx b/src/views-components/process-input-dialog/process-input-dialog.tsx
index 4ba7fd70..2ad0a57f 100644
--- a/src/views-components/process-input-dialog/process-input-dialog.tsx
+++ b/src/views-components/process-input-dialog/process-input-dialog.tsx
@@ -36,7 +36,7 @@ const getInputs = (data: any) =>
         { type: it.type, id: it.id, label: it.label, value: getInputValue(it.id, data.mounts.varLibCwlCwlInputJson.content), disabled: true }
     )) : [];
 
-const getInputValue = (id: string, data: any) => {
+export const getInputValue = (id: string, data: any) => {
     switch (id) {
         case "#main/example_flag":
             return data.exampleFlag;
diff --git a/src/views/process-panel/process-information-card.tsx b/src/views/process-panel/process-information-card.tsx
index 1f42db6b..db0769f1 100644
--- a/src/views/process-panel/process-information-card.tsx
+++ b/src/views/process-panel/process-information-card.tsx
@@ -13,7 +13,7 @@ import { DetailsAttribute } from '~/components/details-attribute/details-attribu
 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";
+import * as classNames from 'classnames';
 
 type CssRules = 'card' | 'iconHeader' | 'label' | 'value' | 'chip' | 'link' | 'content' | 'title' | 'avatar';
 
@@ -70,13 +70,13 @@ export interface ProcessInformationCardDataProps {
     onContextMenu: (event: React.MouseEvent<HTMLElement>) => void;
     openProcessInputDialog: (uuid: string) => void;
     navigateToOutput: (uuid: string) => void;
-    navigateToWorkflow: (uuid: string) => void;
+    openWorkflow: (uuid: string) => void;
 }
 
 type ProcessInformationCardProps = ProcessInformationCardDataProps & WithStyles<CssRules, true>;
 
 export const ProcessInformationCard = withStyles(styles, { withTheme: true })(
-    ({ classes, process, onContextMenu, theme, openProcessInputDialog, navigateToOutput, navigateToWorkflow }: ProcessInformationCardProps) => {
+    ({ classes, process, onContextMenu, theme, openProcessInputDialog, navigateToOutput, openWorkflow }: ProcessInformationCardProps) => {
         const { container } = process;
         const startedAt = container ? formatDate(container.startedAt) : 'N/A';
         const finishedAt = container ? formatDate(container.finishedAt) : 'N/A';
@@ -86,17 +86,17 @@ export const ProcessInformationCard = withStyles(styles, { withTheme: true })(
                     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>
@@ -113,28 +113,28 @@ export const ProcessInformationCard = withStyles(styles, { withTheme: true })(
                         <Typography noWrap variant='body1' 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(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(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)}
-                        />}
+                            label='To'
+                            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}/>
+                            </span>}
                     </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>
diff --git a/src/views/process-panel/process-panel-root.tsx b/src/views/process-panel/process-panel-root.tsx
index 5fb6390c..eb8440f3 100644
--- a/src/views/process-panel/process-panel-root.tsx
+++ b/src/views/process-panel/process-panel-root.tsx
@@ -38,7 +38,7 @@ export const ProcessPanelRoot = ({ process, ...props }: ProcessPanelRootProps) =
                     onContextMenu={event => props.onContextMenu(event, process)}
                     openProcessInputDialog={props.openProcessInputDialog}
                     navigateToOutput={props.navigateToOutput}
-                    navigateToWorkflow={props.navigateToWorkflow}
+                    openWorkflow={props.navigateToWorkflow}
             />
             </Grid>
             <Grid item sm={12} md={5}>

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list