// Copyright (C) The Arvados Authors. All rights reserved. // // SPDX-License-Identifier: AGPL-3.0 import React from 'react'; import { StyleRulesCallback, Card, CardHeader, WithStyles, withStyles, Typography, CardContent, Tooltip, Collapse, Grid } from '@material-ui/core'; import { ArvadosTheme } from 'common/custom-theme'; import { RootState } from 'store/store'; import { connect } from 'react-redux'; import { getResource } from 'store/resources/resources'; import { getPropertyChip } from '../resource-properties-form/property-chip'; import { ProjectResource } from 'models/project'; import { FavoriteStar, PublicFavoriteStar } from 'views-components/favorite-star/favorite-star'; import { FreezeIcon } from 'components/icon/icon'; import { Resource } from 'models/resource'; import { Dispatch } from 'redux'; import { loadDetailsPanel } from 'store/details-panel/details-panel-action'; import { ExpandChevronRight } from 'components/expand-chevron-right/expand-chevron-right'; import { MultiselectToolbar } from 'components/multiselect-toolbar/MultiselectToolbar'; import { setSelectedResourceUuid } from 'store/selected-resource/selected-resource-actions'; import { deselectAllOthers } from 'store/multiselect/multiselect-actions'; type CssRules = | 'root' | 'cardHeaderContainer' | 'cardHeader' | 'descriptionToggle' | 'showMore' | 'noDescription' | 'userNameContainer' | 'cardContent' | 'nameSection' | 'namePlate' | 'faveIcon' | 'frozenIcon' | 'chipToggle' | 'chipSection' | 'tag' | 'description' | 'toolbarStyles'; const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ root: { width: '100%', marginBottom: '1rem', flex: '0 0 auto', padding: 0, minHeight: '3rem', }, noDescription: { color: theme.palette.grey['600'], fontStyle: 'italic', marginLeft: '2rem', }, userNameContainer: { display: 'flex', alignItems: 'center', minHeight: '2.7rem', }, cardHeaderContainer: { width: '100%', display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', }, cardHeader: { minWidth: '30rem', padding: '0.2rem 0.4rem 0.2rem 1rem', }, descriptionToggle: { display: 'flex', flexDirection: 'row', cursor: 'pointer', marginTop: '-0.25rem', paddingBottom: '0.5rem', }, cardContent: { display: 'flex', flexDirection: 'column', paddingTop: 0, paddingLeft: '0.1rem', }, nameSection: { display: 'flex', flexDirection: 'row', alignItems: 'center', }, namePlate: { display: 'flex', flexDirection: 'row', alignItems: 'center', margin: 0, minHeight: '2.7rem', }, faveIcon: { fontSize: '0.8rem', margin: 'auto 0 1rem 0.3rem', color: theme.palette.text.primary, }, frozenIcon: { fontSize: '0.5rem', marginLeft: '0.3rem', height: '1rem', color: theme.palette.text.primary, }, showMore: { marginTop: 0, cursor: 'pointer', }, chipToggle: { display: 'flex', alignItems: 'center', height: '2rem', }, chipSection: { marginBottom: '-2rem', }, tag: { marginRight: '0.75rem', marginBottom: '0.5rem', }, description: { marginTop: 0, marginRight: '2rem', marginBottom: '-0.85rem', }, toolbarStyles: { marginRight: '-1rem', }, }); const mapStateToProps = ({ auth, selectedResourceUuid, resources, properties }: RootState) => { const currentResource = getResource(properties.currentRouteUuid)(resources); const frozenByUser = currentResource && getResource((currentResource as ProjectResource).frozenByUuid as string)(resources); const frozenByFullName = frozenByUser && (frozenByUser as Resource & { fullName: string }).fullName; const isSelected = selectedResourceUuid === properties.currentRouteUuid; return { isAdmin: auth.user?.isAdmin, currentResource, frozenByFullName, isSelected, }; }; const mapDispatchToProps = (dispatch: Dispatch) => ({ handleCardClick: (uuid: string) => { dispatch(loadDetailsPanel(uuid)); dispatch(setSelectedResourceUuid(uuid)); dispatch(deselectAllOthers(uuid)); }, }); type ProjectCardProps = WithStyles & { currentResource: ProjectResource; frozenByFullName: string | undefined; isAdmin: boolean; isSelected: boolean; handleCardClick: (resource: any) => void; }; export const ProjectCard = connect( mapStateToProps, mapDispatchToProps )( withStyles(styles)((props: ProjectCardProps) => { const { classes, currentResource, frozenByFullName, handleCardClick, isSelected } = props; const { name, description, uuid } = currentResource as ProjectResource; const [showDescription, setShowDescription] = React.useState(false); const [showProperties, setShowProperties] = React.useState(false); const toggleDescription = () => { setShowDescription(!showDescription); }; const toggleProperties = () => { setShowProperties(!showProperties); }; return ( handleCardClick(uuid)} data-cy='project-details-card' >
{name} {!!frozenByFullName && ( Project was frozen by {frozenByFullName}} > )}
{!description && ( no description available )} } /> {isSelected && }
ev.stopPropagation()}> {description ? (
) : ( <> )} {typeof currentResource.properties === 'object' && Object.keys(currentResource.properties).length > 0 ? (
{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) )}
) : null}
); }) );