X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/6b72f026b7f9f47b42bc26aaed86b021ce8e0eb6..84d9b41e00a8af3f55616ffd7a0ce47ba31ca484:/services/workbench2/src/views-components/project-details-card/project-details-card.tsx

diff --git a/services/workbench2/src/views-components/project-details-card/project-details-card.tsx b/services/workbench2/src/views-components/project-details-card/project-details-card.tsx
index 4c37281cdd..141d5d7ceb 100644
--- a/services/workbench2/src/views-components/project-details-card/project-details-card.tsx
+++ b/services/workbench2/src/views-components/project-details-card/project-details-card.tsx
@@ -17,29 +17,29 @@ import { FavoriteStar, PublicFavoriteStar } from 'views-components/favorite-star
 import { MoreVerticalIcon, FreezeIcon } from 'components/icon/icon';
 import { Resource } from 'models/resource';
 import { IconButton } from '@material-ui/core';
-import { ContextMenuResource, openUserContextMenu } from 'store/context-menu/context-menu-actions';
+import { ContextMenuResource } from 'store/context-menu/context-menu-actions';
 import { openContextMenu, resourceUuidToContextMenuKind } from 'store/context-menu/context-menu-actions';
 import { CollectionResource } from 'models/collection';
 import { ContextMenuKind } from 'views-components/context-menu/context-menu';
 import { Dispatch } from 'redux';
 import classNames from 'classnames';
 import { loadDetailsPanel } from 'store/details-panel/details-panel-action';
+import { ExpandChevronRight } from 'components/expand-chevron-right/expand-chevron-right';
 
 type CssRules =
     | 'root'
     | 'selected'
     | 'cardHeader'
-    | 'descriptionLabel'
+    | 'descriptionToggle'
     | 'showMore'
     | 'noDescription'
-    | 'nameContainer'
+    | 'userNameContainer'
     | 'cardContent'
-    | 'subHeader'
+    | 'nameSection'
     | 'namePlate'
     | 'faveIcon'
     | 'frozenIcon'
     | 'contextMenuSection'
-    | 'chipSection'
     | 'tag'
     | 'description';
 
@@ -48,46 +48,51 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         width: '100%',
         marginBottom: '1rem',
         flex: '0 0 auto',
-        paddingTop: '0.2rem',
+        padding: 0,
         border: '2px solid transparent',
     },
     selected: {
         border: '2px solid #ccc',
     },
     showMore: {
-        color: theme.palette.primary.main,
         cursor: 'pointer',
+        background: 'linear-gradient(to right, black, transparent)',
+        backgroundClip: 'text',
+        color: 'transparent',
     },
     noDescription: {
         color: theme.palette.grey['600'],
         fontStyle: 'italic',
     },
-    nameContainer: {
+    userNameContainer: {
         display: 'flex',
     },
     cardHeader: {
-        paddingTop: '0.4rem',
+        padding: '0.2rem 0.4rem 0.1rem 1rem',
     },
-    descriptionLabel: {
-        paddingTop: '1rem',
-        marginBottom: 0,
-        minHeight: '2.5rem',
-        marginRight: '0.8rem',
+    descriptionToggle: {
+        display: 'flex',
+        flexDirection: 'row',
+        cursor: 'pointer',
+        paddingBottom: '0.5rem',
     },
     cardContent: {
         display: 'flex',
         flexDirection: 'column',
-        transition: 'height 0.3s ease',
+        marginTop: '-1.75rem',
     },
-    subHeader: {
+    nameSection: {
         display: 'flex',
         flexDirection: 'row',
+        alignItems: 'center',
         justifyContent: 'space-between',
-        marginTop: '-2rem',
     },
     namePlate: {
         display: 'flex',
         flexDirection: 'row',
+        alignItems: 'center',
+        margin: 0,
+        paddingBottom: '0.5rem',
     },
     faveIcon: {
         fontSize: '0.8rem',
@@ -97,7 +102,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     frozenIcon: {
         fontSize: '0.5rem',
         marginLeft: '0.3rem',
-        marginTop: '0.57rem',
+        marginTop: '0.1rem',
         height: '1rem',
         color: theme.palette.text.primary,
     },
@@ -105,18 +110,15 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         display: 'flex',
         flexDirection: 'row',
         alignItems: 'center',
-        marginTop: '0.6rem',
-    },
-    chipSection: {
-        display: 'flex',
-        flexWrap: 'wrap',
+        paddingTop: '0.25rem',
     },
     tag: {
         marginRight: '1rem',
-        marginTop: '0.5rem',
+        marginTop: '1rem',
     },
     description: {
-        marginTop: '1rem',
+        maxWidth: '90%',
+        marginTop: 0,
     },
 });
 
@@ -147,10 +149,11 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
         if (resource.groupClass === 'filter') {
             readOnly = true;
         }
-        const menuKind = dispatch<any>(resourceUuidToContextMenuKind(resource.uuid, readOnly));
+        let menuKind = dispatch<any>(resourceUuidToContextMenuKind(resource.uuid, readOnly));
         if (menuKind === ContextMenuKind.ROOT_PROJECT) {
-            dispatch<any>(openUserContextMenu(event, resource as UserResource));
-        } else if (menuKind && resource) {
+            menuKind = ContextMenuKind.USER_DETAILS;
+        }
+        if (menuKind && resource) {
             dispatch<any>(
                 openContextMenu(event, {
                     name: resource.name,
@@ -239,11 +242,15 @@ const UserCard: React.FC<UserCardProps> = ({ classes, currentResource, handleCon
     const { fullName, uuid } = currentResource as UserResource & { fullName: string };
 
     return (
-        <Card className={classNames(classes.root, isSelected ? classes.selected : '')} onClick={()=>handleCardClick(uuid)} data-cy='user-details-card'>
+        <Card
+            className={classNames(classes.root, isSelected ? classes.selected : '')}
+            onClick={() => handleCardClick(uuid)}
+            data-cy='user-details-card'
+        >
             <CardHeader
                 className={classes.cardHeader}
                 title={
-                    <section className={classes.nameContainer}>
+                    <section className={classes.userNameContainer}>
                         <Typography
                             noWrap
                             variant='h6'
@@ -287,35 +294,54 @@ const ProjectCard: React.FC<ProjectCardProps> = ({ classes, currentResource, fro
     };
 
     return (
-        <Card className={classNames(classes.root, isSelected ? classes.selected : '')} onClick={()=>handleCardClick(uuid)} data-cy='project-details-card'>
+        <Card
+            className={classNames(classes.root, isSelected ? classes.selected : '')}
+            onClick={() => handleCardClick(uuid)}
+            data-cy='project-details-card'
+        >
             <CardHeader
                 className={classes.cardHeader}
                 title={
-                    <section className={classes.namePlate}>
-                        <Typography
-                            noWrap
-                            variant='h6'
-                            style={{ marginRight: '1rem' }}
-                        >
-                            {name}
-                        </Typography>
-                        <FavoriteStar
-                            className={classes.faveIcon}
-                            resourceUuid={currentResource.uuid}
-                        />
-                        <PublicFavoriteStar
-                            className={classes.faveIcon}
-                            resourceUuid={currentResource.uuid}
-                        />
-                        {!!frozenByFullName && (
-                            <Tooltip
-                                className={classes.frozenIcon}
-                                disableFocusListener
-                                title={<span>Project was frozen by {frozenByFullName}</span>}
+                    <section className={classes.nameSection}>
+                        <section className={classes.namePlate}>
+                            <Typography
+                                noWrap
+                                variant='h6'
+                                style={{ marginRight: '1rem' }}
                             >
-                                <FreezeIcon style={{ fontSize: 'inherit' }} />
-                            </Tooltip>
-                        )}
+                                {name}
+                            </Typography>
+                            <FavoriteStar
+                                className={classes.faveIcon}
+                                resourceUuid={currentResource.uuid}
+                            />
+                            <PublicFavoriteStar
+                                className={classes.faveIcon}
+                                resourceUuid={currentResource.uuid}
+                            />
+                            {!!frozenByFullName && (
+                                <Tooltip
+                                    className={classes.frozenIcon}
+                                    disableFocusListener
+                                    title={<span>Project was frozen by {frozenByFullName}</span>}
+                                >
+                                    <FreezeIcon style={{ fontSize: 'inherit' }} />
+                                </Tooltip>
+                            )}
+                        </section>
+                        <section onClick={(ev) => ev.stopPropagation()}>
+                            {typeof currentResource.properties === 'object' && Object.keys(currentResource.properties).length > 0 && (
+                                <CardContent className={classes.cardContent}>
+                                    <Typography component='div'>
+                                        {Object.keys(currentResource.properties).map((k) =>
+                                            Array.isArray(currentResource.properties[k])
+                                                ? currentResource.properties[k].map((v: string) => getPropertyChip(k, v, undefined, classes.tag))
+                                                : getPropertyChip(k, currentResource.properties[k], undefined, classes.tag)
+                                        )}
+                                    </Typography>
+                                </CardContent>
+                            )}
+                        </section>
                     </section>
                 }
                 action={
@@ -323,7 +349,7 @@ const ProjectCard: React.FC<ProjectCardProps> = ({ classes, currentResource, fro
                         <Tooltip
                             title='More options'
                             disableFocusListener
-                            >
+                        >
                             <IconButton
                                 aria-label='More options'
                                 onClick={(ev) => handleContextMenu(ev, currentResource as any, isAdmin)}
@@ -334,40 +360,37 @@ const ProjectCard: React.FC<ProjectCardProps> = ({ classes, currentResource, fro
                     </section>
                 }
             />
-            <CardContent className={classes.cardContent}>
-                <section className={classes.subHeader}>
-                    <section className={classes.chipSection}>
-                        <Typography component='div'>
-                            {typeof currentResource.properties === 'object' &&
-                                Object.keys(currentResource.properties).map((k) =>
-                                    Array.isArray(currentResource.properties[k])
-                                        ? currentResource.properties[k].map((v: string) => getPropertyChip(k, v, undefined, classes.tag))
-                                        : getPropertyChip(k, currentResource.properties[k], undefined, classes.tag)
-                                )}
-                        </Typography>
-                    </section>
-                    <section className={classes.descriptionLabel} onClick={(ev)=>ev.stopPropagation()}>
-                        {description ? (
+            <section onClick={(ev) => ev.stopPropagation()}>
+                {description ? (
+                    <section
+                        onClick={toggleDescription}
+                        className={classes.descriptionToggle}
+                    >
+                        <ExpandChevronRight expanded={showDescription} />
+                        <section className={classes.showMore}>
+                        <Collapse
+                            in={showDescription}
+                            timeout='auto'
+                            collapsedHeight='1.25rem'
+                        >
                             <Typography
-                                className={classes.showMore}
-                                onClick={toggleDescription}
-                                data-cy='toggle-description'
+                                className={classes.description}
+                                data-cy='project-description'
                             >
-                                {!showDescription ? "Show full description" : "Hide full description"}
+                                {description}
                             </Typography>
-                        ) : (
-                            <Typography className={classes.noDescription} data-cy="no-description">no description available</Typography>
-                        )}
-                    </section>
-                </section>
-                <Collapse in={showDescription} timeout='auto'>
-                    <section onClick={(ev)=>ev.stopPropagation()}>
-                        <Typography className={classes.description} data-cy='project-description'>
-                            {description}
-                        </Typography>
+                        </Collapse>
+                        </section>
                     </section>
-                </Collapse>
-            </CardContent>
+                ) : (
+                    <Typography
+                        className={classes.noDescription}
+                        data-cy='no-description'
+                    >
+                        no description available
+                    </Typography>
+                )}
+            </section>
         </Card>
     );
 };
