Skip to content

Commit

Permalink
Merge pull request #240 from graasp/55/itemCard
Browse files Browse the repository at this point in the history
refactor: improve item cards
  • Loading branch information
pyphilia authored Nov 30, 2021
2 parents 0972539 + c8c0446 commit 618cffd
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 163 deletions.
6 changes: 4 additions & 2 deletions cypress/support/commands/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ Cypress.Commands.add('goToHome', () => {
cy.get(`#${NAVIGATION_HOME_LINK_ID}`).click();
});

Cypress.Commands.add('goToItemWithNavigation', (id) => {
Cypress.Commands.add('goToItemWithNavigation', (id, openHidden = false) => {
cy.wait(NAVIGATE_PAUSE);
cy.get(`#${NAVIGATION_HIDDEN_PARENTS_ID}`).click();
if (openHidden) {
cy.get(`#${NAVIGATION_HIDDEN_PARENTS_ID}`).click();
}
cy.get(`#${buildNavigationLink(id)}`).click();
});
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"license": "AGPL-3.0-only",
"dependencies": {
"@graasp/chatbox": "git://github.com/graasp/graasp-chatbox.git#main",
"@graasp/query-client": "git://github.com/graasp/graasp-query-client.git#82/updateDeleteItemsRoute",
"@graasp/ui": "git://github.com/graasp/graasp-ui.git#master",
"@graasp/query-client": "git://github.com/graasp/graasp-query-client.git#85/thumbnails",
"@graasp/ui": "git://github.com/graasp/graasp-ui.git",
"@material-ui/core": "4.11.2",
"@material-ui/icons": "5.0.0-beta.4",
"@material-ui/lab": "4.0.0-alpha.57",
Expand Down Expand Up @@ -56,6 +56,7 @@
"start:ci": "react-scripts -r @cypress/instrument-cra start",
"build": "react-scripts build",
"dist": "env-cmd -f ./.env.production react-scripts build",
"dist:dev": "env-cmd -f ./.env.development react-scripts build",
"test": "env-cmd -f ./.env.test react-scripts test",
"test:once": "env-cmd -f ./.env.test react-scripts test --watchAll=false",
"eject": "react-scripts eject",
Expand Down
11 changes: 2 additions & 9 deletions src/components/context/LayoutContext.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import {
DEFAULT_ITEM_LAYOUT_MODE,
MIN_SCREEN_WIDTH,
} from '../../config/constants';
import { DEFAULT_ITEM_LAYOUT_MODE } from '../../config/constants';

const LayoutContext = React.createContext();

Expand All @@ -22,11 +19,7 @@ const LayoutContextProvider = ({ children }) => {

const [isMainMenuOpen, setIsMainMenuOpen] = useState(true);

// open item panel by default if width allows it
const isItemPanelOpen = window.innerWidth > MIN_SCREEN_WIDTH;
const [isItemMetadataMenuOpen, setIsItemMetadataMenuOpen] = useState(
isItemPanelOpen,
);
const [isItemMetadataMenuOpen, setIsItemMetadataMenuOpen] = useState(false);
const [isChatboxMenuOpen, setIsChatboxMenuOpen] = useState(false);

return (
Expand Down
46 changes: 34 additions & 12 deletions src/components/layout/Navigation.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import Typography from '@material-ui/core/Typography';
import { useTranslation } from 'react-i18next';
import { makeStyles } from '@material-ui/core';
Expand Down Expand Up @@ -42,7 +43,7 @@ const Navigation = () => {
const { data: parents, isLoading: parentIsLoading } = useParents({
id: itemId,
path: itemPath,
enabled: parentsOpen,
enabled: true,
});

if (isItemLoading) {
Expand Down Expand Up @@ -84,36 +85,57 @@ const Navigation = () => {
);
};

const ParentLink = ({ id, name }) => (
<Link key={id} to={buildItemPath(id)}>
<Typography id={buildNavigationLink(id)}>{name}</Typography>
</Link>
);
ParentLink.propTypes = {
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
};

const renderParents = () => {
// nothing to display if no parents
const p = item?.get('path');
if (!p || getParentsIdsFromPath(p).length <= 1) {
return null;
}

// display parents only when needed
// todo: display parents if in database
if (!parentsOpen) {
if (parentIsLoading) {
return (
<Typography
id={NAVIGATION_HIDDEN_PARENTS_ID}
className={classes.parents}
onClick={onParentsClick}
>
{LOADING_CONTENT}
</Typography>
);
}

if (parentIsLoading) {
return <Loader />;
// display parents only when needed
// always display last and first parent
if (!parentsOpen) {
return [
parents?.size >= 1 && (
<ParentLink name={parents.first().name} id={parents.first().id} />
),
parents?.size >= 3 && (
<Typography
id={NAVIGATION_HIDDEN_PARENTS_ID}
className={classes.parents}
onClick={onParentsClick}
>
{LOADING_CONTENT}
</Typography>
),
parents?.size >= 2 && (
<ParentLink name={parents.last().name} id={parents.last().id} />
),
];
}

return parents?.map(({ name, id }) => (
<Link key={id} to={buildItemPath(id)}>
<Typography id={buildNavigationLink(id)}>{name}</Typography>
</Link>
));
return parents?.map(({ name, id }) => <ParentLink name={name} id={id} />);
};

return (
Expand Down
84 changes: 0 additions & 84 deletions src/components/main/CustomCardHeader.js

This file was deleted.

77 changes: 43 additions & 34 deletions src/components/main/Item.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
import React, { useContext } from 'react';
import truncate from 'lodash.truncate';
import PropTypes from 'prop-types';
import { Card as GraaspCard } from '@graasp/ui';
import { makeStyles } from '@material-ui/core/styles';
import truncate from 'lodash.truncate';
import Card from '@material-ui/core/Card';
import CardMedia from '@material-ui/core/CardMedia';
import CardContent from '@material-ui/core/CardContent';
import CardActions from '@material-ui/core/CardActions';
import Typography from '@material-ui/core/Typography';
import CustomCardHeader from './CustomCardHeader';
import { Link } from 'react-router-dom';
import { DESCRIPTION_MAX_LENGTH } from '../../config/constants';
import { buildItemCard } from '../../config/selectors';
import { buildItemCard, buildItemLink } from '../../config/selectors';
import EditButton from '../common/EditButton';
import { isItemUpdateAllowedForUser } from '../../utils/membership';
import { getItemImage, stripHtml } from '../../utils/item';
import ItemMenu from './ItemMenu';
import FavoriteButton from '../common/FavoriteButton';
import PinButton from '../common/PinButton';
import { CurrentUserContext } from '../context/CurrentUserContext';
import { buildItemPath } from '../../config/paths';

const useStyles = makeStyles(() => ({
root: {
maxWidth: 345,
},
media: {
height: 0,
paddingTop: '56.25%', // 16:9
const useStyles = makeStyles({
link: {
textDecoration: 'none',
color: 'inherit',
},
}));
});

const Item = ({ item, memberships }) => {
const classes = useStyles();
Expand All @@ -39,25 +34,39 @@ const Item = ({ item, memberships }) => {
memberId: member?.get('id'),
});

const Actions = (
<>
{!member.isEmpty() && <FavoriteButton member={member} item={item} />}
{enableEdition && (
<>
<EditButton item={item} />
<PinButton item={item} />
</>
)}
</>
);

return (
<Card className={classes.root} id={buildItemCard(id)}>
<CustomCardHeader item={item} canEdit={enableEdition} />
<CardMedia className={classes.media} image={image} title={name} />
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">
{truncate(stripHtml(description), { length: DESCRIPTION_MAX_LENGTH })}
</Typography>
</CardContent>
<CardActions disableSpacing>
{!member.isEmpty() && <FavoriteButton member={member} item={item} />}
{enableEdition && (
<>
<EditButton item={item} />
<PinButton item={item} />
</>
)}
</CardActions>
</Card>
<GraaspCard
description={truncate(stripHtml(description), {
length: DESCRIPTION_MAX_LENGTH,
})}
Actions={Actions}
name={name}
creator={member?.get('name')}
ItemMenu={<ItemMenu item={item} canEdit={enableEdition} />}
image={image}
cardId={buildItemCard(id)}
NameWrapper={({ children }) => (
<Link
to={buildItemPath(id)}
id={buildItemLink(id)}
className={classes.link}
>
{children}
</Link>
)}
/>
);
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/main/ItemsGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const ItemsGrid = (props) => {
}

return itemsInPage.map((item) => (
<Grid key={item.id} item xs={12} sm={6} md={4} lg={3} xl={2}>
<Grid key={item.id} item xs={12} sm={12} md={6} lg={4} xl={2}>
<Item
item={item}
memberships={getMembershipsForItem({ items, memberships, item })}
Expand Down
10 changes: 0 additions & 10 deletions src/components/main/ItemsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,6 @@ const ItemsTable = ({
comparator={textComparator}
sort={defautSortedColumn?.type}
/>
<AgGridColumn
headerName={t('Created At')}
field="createdAt"
flex={3}
type="rightAligned"
valueFormatter={dateColumnFormatter}
sortable
comparator={dateComparator}
sort={defautSortedColumn?.createdAt}
/>
<AgGridColumn
headerName={t('Updated At')}
field="updatedAt"
Expand Down
1 change: 1 addition & 0 deletions src/config/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const UPLOAD_METHOD =
export const ITEM_ICON_MAX_SIZE = 25;

export const USERNAME_MAX_LENGTH = 15;
export const ITEM_NAME_MAX_LENGTH = 15;
export const HEADER_USERNAME_MAX_WIDTH = 120;

export const SHARE_ITEM_MODAL_MIN_WIDTH = 120;
Expand Down
Loading

0 comments on commit 618cffd

Please sign in to comment.