standardized nullish grid cells to display hyphens i nnstead of nothing or (none)
[arvados-workbench2.git] / src / views-components / data-explorer / renderers.tsx
index 245a6597af28581e1a3e953c6c3fd018237d2799..9c24a677bbe7c67e7b16a48bd1cf417569744ba1 100644 (file)
@@ -15,7 +15,7 @@ import {
 import { FavoriteStar, PublicFavoriteStar } from '../favorite-star/favorite-star';
 import { Resource, ResourceKind, TrashableResource } from 'models/resource';
 import {
-    LockIcon,
+    FreezeIcon,
     ProjectIcon,
     FilterGroupIcon,
     CollectionIcon,
@@ -61,6 +61,7 @@ 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 {ContainerRequestResource} from 'models/container-request'
 
 const renderName = (dispatch: Dispatch, item: GroupContentsResource) => {
 
@@ -100,7 +101,7 @@ const FrozenProject = (props: {item: ProjectResource}) => {
     if (props.item.frozenByUuid) {
 
         return <Tooltip onOpen={getFullName} enterDelay={500} title={<span>Project was frozen by {fullUsername}</span>}>
-            <LockIcon style={{ fontSize: "inherit" }}/>
+            <FreezeIcon style={{ fontSize: "inherit" }}/>
         </Tooltip>;
     } else {
         return null;
@@ -207,22 +208,22 @@ export const ResourceLastName = connect(
         return resource || { lastName: '' };
     })(renderLastName);
 
-const renderFullName = (dispatch: Dispatch ,item: { uuid: string, firstName: string, lastName: string }, link?: boolean) => {
+const renderFullName = (dispatch: Dispatchitem: { uuid: string, firstName: string, lastName: string }, link?: boolean) => {
     const displayName = (item.firstName + " " + item.lastName).trim() || item.uuid;
     return link ? <Typography noWrap
         color="primary"
         style={{ 'cursor': 'pointer' }}
         onClick={() => dispatch<any>(navigateToUserProfile(item.uuid))}>
-            {displayName}
+        {displayName}
     </Typography> :
-    <Typography noWrap>{displayName}</Typography>;
+        <Typography noWrap>{displayName}</Typography>;
 }
 
 export const UserResourceFullName = connect(
     (state: RootState, props: { uuid: string, link?: boolean }) => {
         const resource = getResource<UserResource>(props.uuid)(state.resources);
-        return {item: resource || { uuid: '', firstName: '', lastName: '' }, link: props.link};
-    })((props: {item: {uuid: string, firstName: string, lastName: string}, link?: boolean} & DispatchProp<any>) => renderFullName(props.dispatch, props.item, props.link));
+        return { item: resource || { uuid: '', firstName: '', lastName: '' }, link: props.link };
+    })((props: { item: { uuid: string, firstName: string, lastName: string }, link?: boolean } & DispatchProp<any>) => renderFullName(props.dispatch, props.item, props.link));
 
 const renderUuid = (item: { uuid: string }) =>
     <Typography data-cy="uuid" noWrap>
@@ -231,8 +232,8 @@ const renderUuid = (item: { uuid: string }) =>
     </Typography>;
 
 export const ResourceUuid = connect((state: RootState, props: { uuid: string }) => (
-        getResource<UserResource>(props.uuid)(state.resources) || { uuid: '' }
-    ))(renderUuid);
+    getResource<UserResource>(props.uuid)(state.resources) || { uuid: '' }
+))(renderUuid);
 
 const renderEmail = (item: { email: string }) =>
     <Typography noWrap>{item.email}</Typography>;
@@ -250,17 +251,17 @@ enum UserAccountStatus {
     UNKNOWN = ''
 }
 
-const renderAccountStatus = (props: {status: UserAccountStatus}) =>
+const renderAccountStatus = (props: { status: UserAccountStatus }) =>
     <Grid container alignItems="center" wrap="nowrap" spacing={8} data-cy="account-status">
         <Grid item>
             {(() => {
-                switch(props.status) {
+                switch (props.status) {
                     case UserAccountStatus.ACTIVE:
-                        return <ActiveIcon style={{color: '#4caf50', verticalAlign: "middle"}} />;
+                        return <ActiveIcon style={{ color: '#4caf50', verticalAlign: "middle" }} />;
                     case UserAccountStatus.SETUP:
-                        return <SetupIcon style={{color: '#2196f3', verticalAlign: "middle"}} />;
+                        return <SetupIcon style={{ color: '#2196f3', verticalAlign: "middle" }} />;
                     case UserAccountStatus.INACTIVE:
-                        return <InactiveIcon style={{color: '#9e9e9e', verticalAlign: "middle"}} />;
+                        return <InactiveIcon style={{ color: '#9e9e9e', verticalAlign: "middle" }} />;
                     default:
                         return <></>;
                 }
@@ -285,37 +286,37 @@ const getUserAccountStatus = (state: RootState, props: { uuid: string }) => {
     )(state.resources);
 
     if (user) {
-        return user.isActive ? {status: UserAccountStatus.ACTIVE} : permissions.length > 0 ? {status: UserAccountStatus.SETUP} : {status: UserAccountStatus.INACTIVE};
+        return user.isActive ? { status: UserAccountStatus.ACTIVE } : permissions.length > 0 ? { status: UserAccountStatus.SETUP } : { status: UserAccountStatus.INACTIVE };
     } else {
-        return {status: UserAccountStatus.UNKNOWN};
+        return { status: UserAccountStatus.UNKNOWN };
     }
 }
 
 export const ResourceLinkTailAccountStatus = connect(
     (state: RootState, props: { uuid: string }) => {
         const link = getResource<LinkResource>(props.uuid)(state.resources);
-        return link && link.tailKind === ResourceKind.USER ? getUserAccountStatus(state, {uuid: link.tailUuid}) : {status: UserAccountStatus.UNKNOWN};
+        return link && link.tailKind === ResourceKind.USER ? getUserAccountStatus(state, { uuid: link.tailUuid }) : { status: UserAccountStatus.UNKNOWN };
     })(renderAccountStatus);
 
 export const UserResourceAccountStatus = connect(getUserAccountStatus)(renderAccountStatus);
 
 const renderIsHidden = (props: {
-                            memberLinkUuid: string,
-                            permissionLinkUuid: string,
-                            visible: boolean,
-                            canManage: boolean,
-                            setMemberIsHidden: (memberLinkUuid: string, permissionLinkUuid: string, hide: boolean) => void
-                        }) => {
+    memberLinkUuid: string,
+    permissionLinkUuid: string,
+    visible: boolean,
+    canManage: boolean,
+    setMemberIsHidden: (memberLinkUuid: string, permissionLinkUuid: string, hide: boolean) => void
+}) => {
     if (props.memberLinkUuid) {
         return <Checkbox
-                data-cy="user-visible-checkbox"
-                color="primary"
-                checked={props.visible}
-                disabled={!props.canManage}
-                onClick={(e) => {
-                    e.stopPropagation();
-                    props.setMemberIsHidden(props.memberLinkUuid, props.permissionLinkUuid, !props.visible);
-                }} />;
+            data-cy="user-visible-checkbox"
+            color="primary"
+            checked={props.visible}
+            disabled={!props.canManage}
+            onClick={(e) => {
+                e.stopPropagation();
+                props.setMemberIsHidden(props.memberLinkUuid, props.permissionLinkUuid, !props.visible);
+            }} />;
     } else {
         return <Typography />;
     }
@@ -380,7 +381,7 @@ export const VirtualMachineHostname = connect(
         return resource || { hostname: '' };
     })(renderHostname);
 
-const renderVirtualMachineLogin = (login: {user: string}) =>
+const renderVirtualMachineLogin = (login: { user: string }) =>
     <Typography noWrap>{login.user}</Typography>
 
 export const VirtualMachineLogin = connect(
@@ -388,7 +389,7 @@ export const VirtualMachineLogin = connect(
         const permission = getResource<LinkResource>(props.linkUuid)(state.resources);
         const user = getResource<UserResource>(permission?.tailUuid || '')(state.resources);
 
-        return {user: user?.username || permission?.tailUuid || ''};
+        return { user: user?.username || permission?.tailUuid || '' };
     })(renderVirtualMachineLogin);
 
 // Common methods
@@ -465,7 +466,7 @@ export const ResourceLinkClass = connect(
 
 const getResourceDisplayName = (resource: Resource): string => {
     if ((resource as UserResource).kind === ResourceKind.USER
-          && typeof (resource as UserResource).firstName !== 'undefined') {
+        && typeof (resource as UserResource).firstName !== 'undefined') {
         // We can be sure the resource is UserResource
         return getUserDisplayName(resource as UserResource);
     } else {
@@ -539,7 +540,7 @@ const renderLinkDelete = (dispatch: Dispatch, item: LinkResource, canManage: boo
                 </IconButton>
             </Typography>;
     } else {
-      return <Typography noWrap></Typography>;
+        return <Typography noWrap></Typography>;
     }
 }
 
@@ -553,7 +554,7 @@ export const ResourceLinkDelete = connect(
             canManage: link && getResourceLinkCanManage(state, link) && !isBuiltin,
         };
     })((props: { item: LinkResource, canManage: boolean } & DispatchProp<any>) =>
-      renderLinkDelete(props.dispatch, props.item, props.canManage));
+        renderLinkDelete(props.dispatch, props.item, props.canManage));
 
 export const ResourceLinkTailEmail = connect(
     (state: RootState, props: { uuid: string }) => {
@@ -664,17 +665,25 @@ export const ResourceWorkflowStatus = connect(
         };
     })((props: { ownerUuid?: string, uuidPrefix: string }) => renderWorkflowStatus(props.uuidPrefix, props.ownerUuid));
 
-export const ResourceLastModifiedDate = connect(
+const renderProcessState = (processState: string) => <Typography>{processState || '-'}</Typography>
+
+export const ResourceProcessState = connect(
     (state: RootState, props: { uuid: string }) => {
-        const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
-        return { date: resource ? resource.modifiedAt : '' };
-    })((props: { date: string }) => renderDate(props.date));
+        const resource = getResource<ContainerRequestResource>(props.uuid)(state.resources);
+        return { state: resource?.state ? resource.state: '' };
+    })((props: { state: string }) => renderProcessState(props.state));
 
 export const ResourceCreatedAtDate = connect(
     (state: RootState, props: { uuid: string }) => {
         const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
         return { date: resource ? resource.createdAt : '' };
     })((props: { date: string }) => renderDate(props.date));
+    
+export const ResourceLastModifiedDate = connect(
+    (state: RootState, props: { uuid: string }) => {
+        const resource = getResource<GroupContentsResource>(props.uuid)(state.resources);
+        return { date: resource ? resource.modifiedAt : '' };
+    })((props: { date: string }) => renderDate(props.date));
 
 export const ResourceTrashDate = connect(
     (state: RootState, props: { uuid: string }) => {
@@ -706,7 +715,7 @@ export const ResourceFileSize = connect(
 
 const renderOwner = (owner: string) =>
     <Typography noWrap>
-        {owner}
+        {owner || '-'}
     </Typography>;
 
 export const ResourceOwner = connect(
@@ -723,6 +732,60 @@ export const ResourceOwnerName = connect(
         return { owner: ownerName ? ownerName!.name : resource!.ownerUuid };
     })((props: { owner: string }) => renderOwner(props.owner));
 
+export const ResourceUUID = connect(
+    (state: RootState, props: { uuid: string }) => {
+        const resource = getResource<CollectionResource>(props.uuid)(state.resources);
+        return { uuid: resource ? resource.uuid : '' };
+    })((props: { uuid: string }) => renderUuid({uuid: props.uuid}));
+    
+const renderPortableDataHash = (portableDataHash:string | null) => 
+    <Typography noWrap>
+        {portableDataHash ? <>{portableDataHash}
+        <CopyToClipboardSnackbar value={portableDataHash} /></> : '-' }
+    </Typography>
+    
+export const ResourcePortableDataHash = connect(
+    (state: RootState, props: { uuid: string }) => {
+        const resource = getResource<CollectionResource>(props.uuid)(state.resources);
+        // console.log('COLLECTION_RESOIRCE', resource)
+        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>
+}
+
+export const ResourceFileCount = connect(
+    (state: RootState, props: { uuid: string }) => {
+        const resource = getResource<CollectionResource>(props.uuid)(state.resources);
+        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 }) => {
@@ -736,10 +799,17 @@ const userFromID =
             return { uuid: props.uuid, userFullname };
         });
 
-export const ResourceOwnerWithName =
+const ownerFromResourceId =
     compose(
-        userFromID,
-        withStyles({}, { withTheme: true }))
+        connect((state: RootState, props: { uuid: string }) => {
+            const childResource = getResource<GroupContentsResource & UserResource>(props.uuid)(state.resources);
+            return { uuid: childResource ? (childResource as Resource).ownerUuid : '' };
+        }),
+        userFromID
+    );
+
+const _resourceWithName =
+    withStyles({}, { withTheme: true })
         ((props: { uuid: string, userFullname: string, dispatch: Dispatch, theme: ArvadosTheme }) => {
             const { uuid, userFullname, dispatch, theme } = props;
 
@@ -755,6 +825,10 @@ export const ResourceOwnerWithName =
             </Typography>;
         });
 
+export const ResourceOwnerWithName = ownerFromResourceId(_resourceWithName);
+
+export const ResourceWithName = userFromID(_resourceWithName);
+
 export const UserNameFromID =
     compose(userFromID)(
         (props: { uuid: string, displayAsText?: string, userFullname: string, dispatch: Dispatch }) => {
@@ -821,7 +895,7 @@ export const ResponsiblePerson =
 
             return <Typography style={{ color: theme.palette.primary.main }} inline noWrap>
                 {responsiblePersonName} ({uuid})
-                </Typography>;
+            </Typography>;
         });
 
 const renderType = (type: string, subtype: string) =>
@@ -851,6 +925,16 @@ export const CollectionStatus = connect((state: RootState, props: { uuid: string
         : <Typography>head version</Typography>
 );
 
+export const CollectionName = connect((state: RootState, props: { uuid: string, className?: string }) => {
+    return {
+                collection: getResource<CollectionResource>(props.uuid)(state.resources),
+                uuid: props.uuid,
+                className: props.className,
+            };
+})((props: { collection: CollectionResource, uuid: string, className?: string }) =>
+        <Typography className={props.className}>{props.collection?.name || props.uuid}</Typography>
+);
+
 export const ProcessStatus = compose(
     connect((state: RootState, props: { uuid: string }) => {
         return { process: getProcess(props.uuid)(state.resources) };
@@ -858,18 +942,18 @@ export const ProcessStatus = compose(
     withStyles({}, { withTheme: true }))
     ((props: { process?: Process, theme: ArvadosTheme }) =>
         props.process
-        ? <Chip label={getProcessStatus(props.process)}
-            style={{
-                height: props.theme.spacing.unit * 3,
-                width: props.theme.spacing.unit * 12,
-                backgroundColor: getProcessStatusColor(
-                    getProcessStatus(props.process), props.theme),
-                color: props.theme.palette.common.white,
-                fontSize: '0.875rem',
-                borderRadius: props.theme.spacing.unit * 0.625,
-            }}
-        />
-        : <Typography>-</Typography>
+            ? <Chip label={getProcessStatus(props.process)}
+                style={{
+                    height: props.theme.spacing.unit * 3,
+                    width: props.theme.spacing.unit * 12,
+                    backgroundColor: getProcessStatusColor(
+                        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(