@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
181 lines (179 loc) • 6.33 kB
JavaScript
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useEffect, useState } from 'react';
import { makeStyles } from 'tss-react/mui';
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import CardMedia from '@mui/material/CardMedia';
import Divider from '@mui/material/Divider';
import Skeleton from '@mui/material/Skeleton';
import palette from '../../styles/palette';
import { fetchPreviewImage } from '../../services/contentTypes';
import useActiveSiteId from '../../hooks/useActiveSiteId';
const useStyles = makeStyles()(() => ({
defaultCard: {
maxWidth: 345,
cursor: 'pointer'
},
compactCard: {
display: 'flex',
cursor: 'pointer'
},
cardHeader: {
overflow: 'hidden'
},
cardHeaderContentTypography: {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
},
media: {
paddingTop: '75%'
},
compactMedia: {
width: 151,
minWidth: 151
},
selected: {
border: `1px solid ${palette.blue.tint}`
}
}));
function useContentTypePreviewImage(contentTypeName) {
const [src, setSrc] = useState(null);
const site = useActiveSiteId();
useEffect(() => {
fetchPreviewImage(site, contentTypeName).subscribe((response) => {
setSrc(URL.createObjectURL(new Blob([response.response])));
});
}, [contentTypeName, site]);
return src;
}
const DefaultCardContent = (props) => {
const { headerTitle, subheader, classes, imgTitle, contentTypeName } = props;
const src = useContentTypePreviewImage(contentTypeName);
return React.createElement(
React.Fragment,
null,
React.createElement(CardHeader, {
title: headerTitle,
subheader: subheader,
classes: {
content: classes.cardHeader
},
titleTypographyProps: {
variant: 'body1',
title: headerTitle,
classes: { root: classes.cardHeaderContentTypography }
},
subheaderTypographyProps: {
noWrap: true,
title: subheader,
classes: { root: classes.cardHeaderContentTypography }
}
}),
React.createElement(Divider, null),
src && React.createElement(CardMedia, { className: classes.media, image: src, title: imgTitle })
);
};
const CompactCardContent = (props) => {
const { headerTitle, subheader, classes, imgTitle, contentTypeName } = props;
const src = useContentTypePreviewImage(contentTypeName);
return React.createElement(
React.Fragment,
null,
src && React.createElement(CardMedia, { className: classes.compactMedia, image: src, title: imgTitle }),
React.createElement(CardHeader, {
title: headerTitle,
subheader: subheader,
classes: {
root: classes.cardHeader,
content: classes.cardHeader
},
titleTypographyProps: {
variant: 'body1',
title: headerTitle,
classes: { root: classes.cardHeaderContentTypography }
},
subheaderTypographyProps: {
noWrap: true,
title: subheader,
classes: { root: classes.cardHeaderContentTypography }
}
})
);
};
export function NewContentCard(props) {
const { onClick, isCompact, isSelected } = props;
const { classes, cx } = useStyles();
const rootClass = !isCompact ? classes.defaultCard : classes.compactCard;
const [hover, setHover] = useState(false);
return React.createElement(
Card,
{
className: cx(rootClass, isSelected && classes.selected),
onClick: onClick,
elevation: hover ? 3 : 1,
onMouseEnter: () => setHover(true),
onMouseLeave: () => setHover(false)
},
!isCompact
? React.createElement(DefaultCardContent, Object.assign({}, props, { classes: classes }))
: React.createElement(CompactCardContent, Object.assign({}, props, { classes: classes }))
);
}
export function ContentSkeletonCard(props) {
const { classes } = useStyles();
const rootClass = !props.isCompact ? classes.defaultCard : classes.compactCard;
return React.createElement(
Card,
{ className: rootClass },
!props.isCompact
? React.createElement(
React.Fragment,
null,
React.createElement(CardHeader, {
title: React.createElement(Skeleton, { animation: 'wave', height: 10, width: '40%' }),
subheader: React.createElement(Skeleton, { animation: 'wave', height: 10, width: '80%' })
}),
React.createElement(Skeleton, { animation: 'wave', variant: 'rectangular', className: classes.media })
)
: React.createElement(
React.Fragment,
null,
React.createElement(Skeleton, { animation: 'wave', variant: 'rectangular', className: classes.compactMedia }),
React.createElement(CardHeader, {
title: React.createElement(Skeleton, { animation: 'wave', height: 10, width: '40%' }),
subheader: React.createElement(Skeleton, { animation: 'wave', height: 10, width: '80%' })
})
)
);
}
export default NewContentCard;