1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-19 05:09:43 +02:00
planka/client/src/components/CardModal/Attachments/Attachments.jsx

162 lines
4.3 KiB
React
Raw Normal View History

2020-04-21 05:04:34 +05:00
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
2022-06-20 18:27:39 +02:00
import { Gallery, Item as GalleryItem } from 'react-photoswipe-gallery';
import { Button } from 'semantic-ui-react';
import { useToggle } from '../../../lib/hooks';
2020-04-21 05:04:34 +05:00
import Item from './Item';
import styles from './Attachments.module.scss';
2022-06-20 18:27:39 +02:00
const INITIALLY_VISIBLE = 4;
const Attachments = React.memo(
({ items, onUpdate, onDelete, onCoverUpdate, onGalleryOpen, onGalleryClose }) => {
const [t] = useTranslation();
const [isAllVisible, toggleAllVisible] = useToggle();
const handleCoverSelect = useCallback(
(id) => {
onCoverUpdate(id);
},
[onCoverUpdate],
);
const handleCoverDeselect = useCallback(() => {
onCoverUpdate(null);
}, [onCoverUpdate]);
const handleUpdate = useCallback(
(id, data) => {
onUpdate(id, data);
},
[onUpdate],
);
const handleDelete = useCallback(
(id) => {
onDelete(id);
},
[onDelete],
);
const handleBeforeGalleryOpen = useCallback(
(gallery) => {
onGalleryOpen();
gallery.on('destroy', () => {
onGalleryClose();
});
},
[onGalleryOpen, onGalleryClose],
);
const handleToggleAllVisibleClick = useCallback(() => {
toggleAllVisible();
}, [toggleAllVisible]);
const galleryItemsNode = items.map((item, index) => {
const isPdf = item.url.endsWith('.pdf');
let props;
if (item.image) {
props = item.image;
} else {
props = {
content: isPdf ? (
// eslint-disable-next-line jsx-a11y/alt-text
<object
data={item.url}
type="application/pdf"
className={classNames(styles.content, styles.contentPdf)}
/>
) : (
<span className={classNames(styles.content, styles.contentError)}>
{t('common.thereIsNoPreviewAvailableForThisAttachment')}
</span>
),
};
}
2022-06-20 18:27:39 +02:00
const isVisible = isAllVisible || index < INITIALLY_VISIBLE;
return (
<GalleryItem
{...props} // eslint-disable-line react/jsx-props-no-spreading
2020-04-21 05:04:34 +05:00
key={item.id}
2022-06-20 18:27:39 +02:00
original={item.url}
caption={item.name}
>
{({ ref, open }) =>
isVisible ? (
<Item
ref={ref}
name={item.name}
url={item.url}
coverUrl={item.coverUrl}
createdAt={item.createdAt}
isCover={item.isCover}
isPersisted={item.isPersisted}
onClick={item.image || isPdf ? open : undefined}
2022-06-20 18:27:39 +02:00
onCoverSelect={() => handleCoverSelect(item.id)}
onCoverDeselect={handleCoverDeselect}
onUpdate={(data) => handleUpdate(item.id, data)}
onDelete={() => handleDelete(item.id)}
/>
) : (
<span ref={ref} />
)
}
2022-06-20 18:27:39 +02:00
</GalleryItem>
);
});
return (
<>
<Gallery
withCaption
withDownloadButton
options={{
showHideAnimationType: 'none',
closeTitle: '',
zoomTitle: '',
arrowPrevTitle: '',
arrowNextTitle: '',
errorMsg: '',
}}
onBeforeOpen={handleBeforeGalleryOpen}
>
{galleryItemsNode}
</Gallery>
{items.length > INITIALLY_VISIBLE && (
<Button
fluid
content={
isAllVisible
? t('action.showFewerAttachments')
: t('action.showAllAttachments', {
hidden: items.length - INITIALLY_VISIBLE,
})
}
className={styles.toggleButton}
onClick={handleToggleAllVisibleClick}
/>
)}
</>
);
},
);
2020-04-21 05:04:34 +05:00
Attachments.propTypes = {
items: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
onUpdate: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
2020-04-23 03:02:53 +05:00
onCoverUpdate: PropTypes.func.isRequired,
2022-06-20 18:27:39 +02:00
onGalleryOpen: PropTypes.func.isRequired,
onGalleryClose: PropTypes.func.isRequired,
2020-04-21 05:04:34 +05:00
};
export default Attachments;