Merge branch '18368-notification-banner' into 19836-new-tooltip-impl
[arvados.git] / src / views-components / data-explorer / renderers.tsx
index aa555a00af8fcfb6a164cf349a6cf1573e84d4c7..d274157c48e2b1cd22804179fa33954c4b8fb361 100644 (file)
@@ -36,7 +36,7 @@ import { connect, DispatchProp } from 'react-redux';
 import { RootState } from 'store/store';
 import { getResource, filterResources } from 'store/resources/resources';
 import { GroupContentsResource } from 'services/groups-service/groups-service';
-import { getProcess, Process, getProcessStatus, getProcessStatusColor, getProcessRuntime } from 'store/processes/process';
+import { getProcess, Process, getProcessStatus, getProcessStatusStyles, getProcessRuntime } from 'store/processes/process';
 import { ArvadosTheme } from 'common/custom-theme';
 import { compose, Dispatch } from 'redux';
 import { WorkflowResource } from 'models/workflow';
@@ -61,9 +61,10 @@ import { getUserUuid } from 'common/getuser';
 import { VirtualMachinesResource } from 'models/virtual-machines';
 import { CopyToClipboardSnackbar } from 'components/copy-to-clipboard-snackbar/copy-to-clipboard-snackbar';
 import { ProjectResource } from 'models/project';
+import { ProcessResource } from 'models/process';
 
-const renderName = (dispatch: Dispatch, item: GroupContentsResource) => {
 
+const renderName = (dispatch: Dispatch, item: GroupContentsResource) => {
     const navFunc = ("groupClass" in item && item.groupClass === GroupClass.ROLE ? navigateToGroupDetails : navigateTo);
     return <Grid container alignItems="center" wrap="nowrap" spacing={16}>
         <Grid item>
@@ -89,6 +90,7 @@ const renderName = (dispatch: Dispatch, item: GroupContentsResource) => {
     </Grid>;
 };
 
+
 const FrozenProject = (props: {item: ProjectResource}) => {
     const [fullUsername, setFullusername] = React.useState<any>(null);
     const getFullName = React.useCallback(() => {
@@ -113,6 +115,7 @@ export const ResourceName = connect(
         return resource;
     })((resource: GroupContentsResource & DispatchProp<any>) => renderName(resource.dispatch, resource));
 
+    
 const renderIcon = (item: GroupContentsResource) => {
     switch (item.kind) {
         case ResourceKind.PROJECT:
@@ -230,6 +233,11 @@ const renderUuid = (item: { uuid: string }) =>
         {(item.uuid && <CopyToClipboardSnackbar value={item.uuid} />) || '-' }
     </Typography>;
 
+const renderUuidCopyIcon = (item: { uuid: string }) =>
+    <Typography data-cy="uuid" noWrap>
+        {(item.uuid && <CopyToClipboardSnackbar value={item.uuid} />) || '-' }
+    </Typography>;
+
 export const ResourceUuid = connect((state: RootState, props: { uuid: string }) => (
     getResource<UserResource>(props.uuid)(state.resources) || { uuid: '' }
 ))(renderUuid);
@@ -446,7 +454,7 @@ export const ResourceCluster = (props: { uuid: string }) => {
 
 // Links Resources
 const renderLinkName = (item: { name: string }) =>
-    <Typography noWrap>{item.name || '(none)'}</Typography>;
+    <Typography noWrap>{item.name || '-'}</Typography>;
 
 export const ResourceLinkName = connect(
     (state: RootState, props: { uuid: string }) => {
@@ -664,37 +672,59 @@ export const ResourceWorkflowStatus = connect(
         };
     })((props: { ownerUuid?: string, uuidPrefix: string }) => renderWorkflowStatus(props.uuidPrefix, props.ownerUuid));
 
-const renderProcessState = (processState: string) => <Typography>{processState || '-'}</Typography>
-
-export const ResourceProcessState = connect(
-    (state: RootState, props: { uuid: string }) => {
-        const process = getProcess(props.uuid)(state.resources)
-        // console.log('PROCESS>>>', process)
-        return { state: process?.container?.state ? process?.container?.state : '' };
-    })((props: { state: string }) => renderProcessState(props.state));
-
-export const ResourceProcessUuid = connect(
+export const ResourceContainerUuid = connect(
     (state: RootState, props: { uuid: string }) => {
         const process = getProcess(props.uuid)(state.resources)
         return { uuid: process?.container?.uuid ? process?.container?.uuid : '' };
     })((props: { uuid: string }) => renderUuid({ uuid: props.uuid }));
 
+enum ColumnSelection {
+    OUTPUT_UUID = 'outputUuid',
+    LOG_UUID = 'logUuid'
+}
+
+const renderUuidLinkWithCopyIcon = (dispatch: Dispatch, item: ProcessResource, column: string) => {
+    const selectedColumnUuid = item[column]
+    return <Grid container alignItems="center" wrap="nowrap" >
+        <Grid item>
+            {selectedColumnUuid ? 
+                <Typography color="primary" style={{ width: 'auto', cursor: 'pointer' }} noWrap 
+                    onClick={() => dispatch<any>(navigateTo(selectedColumnUuid))}>
+                    {selectedColumnUuid} 
+                </Typography> 
+            : '-' }
+        </Grid>
+        <Grid item>
+            {selectedColumnUuid && renderUuidCopyIcon({ uuid: selectedColumnUuid })}
+        </Grid>
+    </Grid>;
+};
 
 export const ResourceOutputUuid = connect(
     (state: RootState, props: { uuid: string }) => {
-        const process = getProcess(props.uuid)(state.resources)
-        const outputUuid = process?.containerRequest.outputUuid
-        return { uuid: outputUuid ? outputUuid : '' };
-    })((props: { uuid: string }) => renderUuid({ uuid: props.uuid }));
+        const resource = getResource<ProcessResource>(props.uuid)(state.resources);
+        return resource;
+    })((process: ProcessResource & DispatchProp<any>) => renderUuidLinkWithCopyIcon(process.dispatch, process, ColumnSelection.OUTPUT_UUID));
+
+export const ResourceLogUuid = connect(
+    (state: RootState, props: { uuid: string }) => {
+        const resource = getResource<ProcessResource>(props.uuid)(state.resources);
+        return resource;
+    })((process: ProcessResource & DispatchProp<any>) => renderUuidLinkWithCopyIcon(process.dispatch, process, ColumnSelection.LOG_UUID));
 
 export const ResourceParentProcess = connect(
     (state: RootState, props: { uuid: string }) => {
         const process = getProcess(props.uuid)(state.resources)
-        const parentProcessUuid = process?.containerRequest?.requestingContainerUuid
-        return { parentProcess: parentProcessUuid || '' };
+        return { parentProcess: process?.containerRequest?.requestingContainerUuid || '' };
     })((props: { parentProcess: string }) => renderUuid({uuid: props.parentProcess}));
 
-export const ResourceCreatedAtDate = connect(
+export const ResourceModifiedByUserUuid = connect(
+    (state: RootState, props: { uuid: string }) => {
+        const process = getProcess(props.uuid)(state.resources)
+        return { userUuid: process?.containerRequest?.modifiedByUserUuid || '' };
+    })((props: { userUuid: string }) => renderUuid({uuid: props.userUuid}));
+
+    export const ResourceCreatedAtDate = connect(
     (state: RootState, props: { uuid: string }) => {
         const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
         return { date: resource ? resource.createdAt : '' };
@@ -758,6 +788,16 @@ export const ResourceUUID = connect(
         const resource = getResource<CollectionResource>(props.uuid)(state.resources);
         return { uuid: resource ? resource.uuid : '' };
     })((props: { uuid: string }) => renderUuid({uuid: props.uuid}));
+
+const renderVersion = (version: number) =>{
+    return <Typography>{version ?? '-'}</Typography>
+}
+
+export const ResourceVersion = connect(
+    (state: RootState, props: { uuid: string }) => {
+        const resource = getResource<CollectionResource>(props.uuid)(state.resources);
+        return { version: resource ? resource.version: '' };
+    })((props: { version: number }) => renderVersion(props.version));
     
 const renderPortableDataHash = (portableDataHash:string | null) => 
     <Typography noWrap>
@@ -771,20 +811,6 @@ export const ResourcePortableDataHash = connect(
         return { portableDataHash: resource ? resource.portableDataHash : '' };    
     })((props: { portableDataHash: string }) => renderPortableDataHash(props.portableDataHash));
 
-const renderVersion = (version: number) =>{
-    return <Typography>{version ?? '-'}</Typography>
-}
-
-export const ResourceVersion = connect(
-    (state: RootState, props: { uuid: string }) => {
-        const resource = getResource<CollectionResource>(props.uuid)(state.resources);
-        return { version: resource ? resource.version: '' };
-    })((props: { version: number }) => renderVersion(props.version));
-
-const renderDescription = (description: string)=>{
-    const truncatedDescription = description ? description.slice(0, 18) + '...' : '-'
-    return <Typography title={description}>{truncatedDescription}</Typography>;
-}
 
 const renderFileCount = (fileCount: number) =>{
     return <Typography>{fileCount ?? '-'}</Typography>
@@ -796,16 +822,6 @@ export const ResourceFileCount = connect(
         return { fileCount: resource ? resource.fileCount: '' };
     })((props: { fileCount: number }) => renderFileCount(props.fileCount));
 
-export const ResourceDescription = connect(
-    (state: RootState, props: { uuid: string }) => {
-        const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
-        //testing---------------
-        // const containerRequestDescription = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
-        // if (resource && !resource.description && resource.kind === ResourceKind.PROCESS) resource.description = containerRequestDescription
-        //testing---------------
-        return { description: resource ? resource.description : '' };
-    })((props: { description: string }) => renderDescription(props.description));
-
 const userFromID =
     connect(
         (state: RootState, props: { uuid: string }) => {
@@ -828,11 +844,14 @@ const ownerFromResourceId =
         userFromID
     );
 
+
+
+
+
 const _resourceWithName =
     withStyles({}, { withTheme: true })
         ((props: { uuid: string, userFullname: string, dispatch: Dispatch, theme: ArvadosTheme }) => {
             const { uuid, userFullname, dispatch, theme } = props;
-
             if (userFullname === '') {
                 dispatch<any>(loadResource(uuid, false));
                 return <Typography style={{ color: theme.palette.primary.main }} inline noWrap>
@@ -849,6 +868,8 @@ export const ResourceOwnerWithName = ownerFromResourceId(_resourceWithName);
 
 export const ResourceWithName = userFromID(_resourceWithName);
 
+
+
 export const UserNameFromID =
     compose(userFromID)(
         (props: { uuid: string, displayAsText?: string, userFullname: string, dispatch: Dispatch }) => {
@@ -966,15 +987,14 @@ export const ProcessStatus = compose(
                 style={{
                     height: props.theme.spacing.unit * 3,
                     width: props.theme.spacing.unit * 12,
-                    backgroundColor: getProcessStatusColor(
+                    ...getProcessStatusStyles(
                         getProcessStatus(props.process), props.theme),
-                    color: props.theme.palette.common.white,
                     fontSize: '0.875rem',
                     borderRadius: props.theme.spacing.unit * 0.625,
                 }}
             />
             : <Typography>-</Typography>
-    );
+        );
 
 export const ProcessStartDate = connect(
     (state: RootState, props: { uuid: string }) => {
@@ -1022,6 +1042,6 @@ export const ContainerRunTime = connect((state: RootState, props: { uuid: string
     }
 
     render() {
-        return renderRunTime(this.state.runtime);
+        return this.props.process ? renderRunTime(this.state.runtime) : <Typography>-</Typography>;
     }
 });