diff --git a/package.json b/package.json index a120860292..5a2f7f69f6 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "mongoose-hidden": "^1.8.1", "mongoose-paginate-v2": "^1.3.6", "nodemailer": "^6.4.2", + "object-to-formdata": "^3.0.9", "passport": "^0.4.1", "passport-anonymous": "^1.0.1", "passport-headerapikey": "^1.2.1", diff --git a/src/client/components/elements/IconButton/index.js b/src/client/components/elements/IconButton/index.js deleted file mode 100644 index 7f9ab900d6..0000000000 --- a/src/client/components/elements/IconButton/index.js +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import Button from '../Button'; -import Plus from '../../icons/Plus'; -import X from '../../icons/X'; -import Chevron from '../../icons/Chevron'; - -import './index.scss'; - -const baseClass = 'icon-button'; - -const IconButton = React.forwardRef(({ iconName, className, ...rest }, ref) => { - const classes = [ - baseClass, - className && className, - `${baseClass}--${iconName}`, - ].filter(Boolean).join(' '); - - const icons = { - Plus, - X, - Chevron, - }; - - const Icon = icons[iconName] || icons.arrow; - - return ( - - - - ); -}); - -IconButton.defaultProps = { - className: '', -}; - -IconButton.propTypes = { - iconName: PropTypes.oneOf(['Chevron', 'X', 'Plus']).isRequired, - className: PropTypes.string, -}; - -export default IconButton; diff --git a/src/client/components/elements/IconButton/index.scss b/src/client/components/elements/IconButton/index.scss deleted file mode 100644 index 5b8fcb9eb5..0000000000 --- a/src/client/components/elements/IconButton/index.scss +++ /dev/null @@ -1,24 +0,0 @@ -@import '../../../scss/styles.scss'; - -.icon-button { - line-height: 0; - background-color: transparent; - margin-top: 0; - @include color-svg($color-gray ); - - &:hover, - &:focus { - background-color: transparent; - @include color-svg($color-dark-gray); - } - - &.btn { - padding: 5px; - } - - &--crossOut { - svg { - transform: rotate(45deg); - } - } -} diff --git a/src/client/components/elements/Paginator/index.js b/src/client/components/elements/Paginator/index.js index 50b6eb32bd..34312601c7 100644 --- a/src/client/components/elements/Paginator/index.js +++ b/src/client/components/elements/Paginator/index.js @@ -29,15 +29,21 @@ const Pagination = (props) => { prevPage, nextPage, numberOfNeighbors, + disableHistoryChange, + onChange, } = props; if (!totalPages || totalPages <= 1) return null; // uses react router to set the current page const updatePage = (page) => { - const params = queryString.parse(location.search, { ignoreQueryPrefix: true }); - params.page = page; - history.push({ search: queryString.stringify(params, { addQueryPrefix: true }) }); + if (!disableHistoryChange) { + const params = queryString.parse(location.search, { ignoreQueryPrefix: true }); + params.page = page; + history.push({ search: queryString.stringify(params, { addQueryPrefix: true }) }); + } + + if (typeof onChange === 'function') onChange(page); }; // Create array of integers for each page @@ -139,6 +145,8 @@ Pagination.defaultProps = { prevPage: null, nextPage: null, numberOfNeighbors: 1, + disableHistoryChange: false, + onChange: undefined, }; Pagination.propTypes = { @@ -150,4 +158,6 @@ Pagination.propTypes = { prevPage: PropTypes.number, nextPage: PropTypes.number, numberOfNeighbors: PropTypes.number, + disableHistoryChange: PropTypes.bool, + onChange: PropTypes.func, }; diff --git a/src/client/components/elements/Thumbnail/index.js b/src/client/components/elements/Thumbnail/index.js index ebbdcaa8df..e8d1bb3dae 100644 --- a/src/client/components/elements/Thumbnail/index.js +++ b/src/client/components/elements/Thumbnail/index.js @@ -50,7 +50,7 @@ Thumbnail.propTypes = { adminThumbnail: PropTypes.string, mimeType: PropTypes.string, staticURL: PropTypes.string.isRequired, - size: PropTypes.oneOf(['small', 'medium', 'large']), + size: PropTypes.oneOf(['small', 'medium', 'large', 'expand']), }; export default Thumbnail; diff --git a/src/client/components/elements/Thumbnail/index.scss b/src/client/components/elements/Thumbnail/index.scss index 7fea756467..91fde3e3f9 100644 --- a/src/client/components/elements/Thumbnail/index.scss +++ b/src/client/components/elements/Thumbnail/index.scss @@ -12,13 +12,29 @@ object-fit: cover; } + &--size-expand { + max-height: 100%; + width: 100%; + padding-top: 100%; + position: relative; + + img, svg { + position: absolute; + } + } + + &--size-large { + max-height: base(9); + width: base(9); + } + &--size-medium { - max-height: base(6); + max-height: base(7); width: base(7); } &--size-small { - max-height: base(4); + max-height: base(5); width: base(5); } diff --git a/src/client/components/elements/UploadCard/index.js b/src/client/components/elements/UploadCard/index.js new file mode 100644 index 0000000000..0958bd1922 --- /dev/null +++ b/src/client/components/elements/UploadCard/index.js @@ -0,0 +1,69 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Thumbnail from '../Thumbnail'; + +import './index.scss'; + +const baseClass = 'upload-card'; + +const UploadCard = (props) => { + const { + onClick, + mimeType, + sizes, + filename, + collection: { + upload: { + adminThumbnail, + staticURL, + } = {}, + } = {}, + } = props; + + const classes = [ + baseClass, + typeof onClick === 'function' && `${baseClass}--has-on-click`, + ].filter(Boolean).join(' '); + + return ( +