1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-20 05:39:43 +02:00
planka/client/src/components/Project/ActionsPopup/BackgroundEditStep.jsx

177 lines
5 KiB
React
Raw Normal View History

2020-08-20 15:35:46 +05:00
import { dequal } from 'dequal';
import upperFirst from 'lodash/upperFirst';
import camelCase from 'lodash/camelCase';
2020-05-26 00:46:04 +05:00
import React, { useCallback, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
2020-05-26 00:46:04 +05:00
import { useTranslation } from 'react-i18next';
import { Button, Image } from 'semantic-ui-react';
2020-05-26 00:46:04 +05:00
import { FilePicker, Popup } from '../../../lib/custom-ui';
import ProjectBackgroundGradients from '../../../constants/ProjectBackgroundGradients';
2020-06-03 22:27:20 +05:00
import { ProjectBackgroundTypes } from '../../../constants/Enums';
import styles from './BackgroundEditStep.module.scss';
import globalStyles from '../../../styles.module.scss';
2020-05-26 00:46:04 +05:00
const BackgroundEditStep = React.memo(
({
defaultValue,
imageCoverUrl,
isImageUpdating,
onUpdate,
onImageUpdate,
onImageDelete,
onBack,
}) => {
2020-05-26 00:46:04 +05:00
const [t] = useTranslation();
const field = useRef(null);
const handleGradientClick = useCallback(
(_, { value }) => {
const background = {
2020-06-03 22:27:20 +05:00
type: ProjectBackgroundTypes.GRADIENT,
name: value,
};
if (!dequal(background, defaultValue)) {
2020-06-03 22:27:20 +05:00
onUpdate(background);
}
},
[defaultValue, onUpdate],
);
const handleImageClick = useCallback(() => {
const background = {
2020-06-03 22:27:20 +05:00
type: ProjectBackgroundTypes.IMAGE,
};
if (!dequal(background, defaultValue)) {
onUpdate(background);
}
}, [defaultValue, onUpdate]);
2020-05-26 00:46:04 +05:00
const handleFileSelect = useCallback(
(file) => {
onImageUpdate({
file,
});
},
[onImageUpdate],
);
const handleDeleteImageClick = useCallback(() => {
onImageDelete();
}, [onImageDelete]);
const handleRemoveClick = useCallback(() => {
onUpdate(null);
}, [onUpdate]);
2020-05-26 00:46:04 +05:00
useEffect(() => {
field.current.focus();
}, []);
return (
<>
<Popup.Header onBack={onBack}>
{t('common.editBackground', {
context: 'title',
})}
</Popup.Header>
<Popup.Content>
<div className={styles.gradientButtons}>
{ProjectBackgroundGradients.map((gradient) => (
<Button
key={gradient}
type="button"
name="gradient"
value={gradient}
className={classNames(
styles.gradientButton,
defaultValue &&
2020-06-03 22:27:20 +05:00
defaultValue.type === ProjectBackgroundTypes.GRADIENT &&
gradient === defaultValue.name &&
styles.gradientButtonActive,
globalStyles[`background${upperFirst(camelCase(gradient))}`],
)}
onClick={handleGradientClick}
/>
))}
</div>
{imageCoverUrl && (
/* TODO: wrap in button */
<Image
src={imageCoverUrl}
label={
defaultValue &&
defaultValue.type === 'image' && {
corner: 'left',
size: 'small',
icon: {
name: 'star',
color: 'grey',
inverted: true,
},
className: styles.imageLabel,
}
}
className={styles.image}
onClick={handleImageClick}
/>
)}
2020-05-26 00:46:04 +05:00
<div className={styles.action}>
<FilePicker accept="image/*" onSelect={handleFileSelect}>
<Button
ref={field}
content={t('action.uploadNewImage')}
2020-05-26 00:46:04 +05:00
loading={isImageUpdating}
disabled={isImageUpdating}
className={styles.actionButton}
/>
</FilePicker>
</div>
{imageCoverUrl && (
<div className={styles.action}>
<Button
content={t('action.deleteImage')}
disabled={isImageUpdating}
className={styles.actionButton}
onClick={handleDeleteImageClick}
/>
</div>
)}
2020-05-26 00:46:04 +05:00
{defaultValue && (
<div className={styles.action}>
<Button
content={t('action.removeBackground')}
disabled={isImageUpdating}
className={styles.actionButton}
onClick={handleRemoveClick}
/>
</div>
2020-05-26 00:46:04 +05:00
)}
</Popup.Content>
</>
);
},
);
BackgroundEditStep.propTypes = {
2020-05-26 00:46:04 +05:00
defaultValue: PropTypes.object, // eslint-disable-line react/forbid-prop-types
imageCoverUrl: PropTypes.string,
2020-05-26 00:46:04 +05:00
isImageUpdating: PropTypes.bool.isRequired,
onUpdate: PropTypes.func.isRequired,
2020-05-26 00:46:04 +05:00
onImageUpdate: PropTypes.func.isRequired,
onImageDelete: PropTypes.func.isRequired,
onBack: PropTypes.func.isRequired,
};
BackgroundEditStep.defaultProps = {
2020-05-26 00:46:04 +05:00
defaultValue: undefined,
imageCoverUrl: undefined,
2020-05-26 00:46:04 +05:00
};
export default BackgroundEditStep;