diff --git a/client/src/actions/cards.js b/client/src/actions/cards.js index 0969910..509c3f7 100644 --- a/client/src/actions/cards.js +++ b/client/src/actions/cards.js @@ -89,6 +89,35 @@ const handleCardDelete = (card) => ({ }, }); +const copyCard = (id) => ({ + type: ActionTypes.CARD_COPY, + payload: { + id, + }, +}); + +copyCard.success = (card) => ({ + type: ActionTypes.CARD_COPY__SUCCESS, + payload: { + card, + }, +}); + +copyCard.failure = (id, error) => ({ + type: ActionTypes.CARD_COPY__FAILURE, + payload: { + id, + error, + }, +}); + +const handleCardCopy = (card) => ({ + type: ActionTypes.CARD_COPY_HANDLE, + payload: { + card, + }, +}); + export default { createCard, handleCardCreate, @@ -96,4 +125,6 @@ export default { handleCardUpdate, deleteCard, handleCardDelete, + copyCard, + handleCardCopy, }; diff --git a/client/src/components/BoardActions/Filters.jsx b/client/src/components/BoardActions/Filters.jsx index c4e61c6..5542f51 100644 --- a/client/src/components/BoardActions/Filters.jsx +++ b/client/src/components/BoardActions/Filters.jsx @@ -25,6 +25,7 @@ const Filters = React.memo( onLabelUpdate, onLabelMove, onLabelDelete, + // onCopyCard, }) => { const [t] = useTranslation(); @@ -83,6 +84,7 @@ const Filters = React.memo( onUpdate={onLabelUpdate} onMove={onLabelMove} onDelete={onLabelDelete} + // onCopyCard={onCopyCard} > - - )} - - ) : ( - // eslint-disable-next-line react/jsx-props-no-spreading - - {item.name} - - )} + {item.name} + + {canEdit && ( + handleUpdate(item.id, data)} + onDelete={() => handleDelete(item.id)} + onCopyCard={onCopyCard} + > + + + )} + + ) : ( + // eslint-disable-next-line react/jsx-props-no-spreading + + {item.name} + + )} + - - )} - - )); + )} + + )); - return ( -
-
- - - {({ innerRef, droppableProps, placeholder }) => ( - // eslint-disable-next-line react/jsx-props-no-spreading -
- {itemsNode} - {placeholder} - {canEdit && ( - -
- )} -
-
+ return ( +
+
+ + + {({ innerRef, droppableProps, placeholder }) => ( + // eslint-disable-next-line react/jsx-props-no-spreading +
+ {itemsNode} + {placeholder} + {canEdit && ( + +
+ )} +
+
+
-
- ); -}); + ); + }, +); Boards.propTypes = { items: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types @@ -132,6 +135,7 @@ Boards.propTypes = { onUpdate: PropTypes.func.isRequired, onMove: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired, + onCopyCard: PropTypes.func.isRequired, }; Boards.defaultProps = { diff --git a/client/src/components/Card/ActionsStep.jsx b/client/src/components/Card/ActionsStep.jsx index dbd349e..185b4d1 100644 --- a/client/src/components/Card/ActionsStep.jsx +++ b/client/src/components/Card/ActionsStep.jsx @@ -12,6 +12,7 @@ import DueDateEditStep from '../DueDateEditStep'; import StopwatchEditStep from '../StopwatchEditStep'; import CardMoveStep from '../CardMoveStep'; import DeleteStep from '../DeleteStep'; +import CardCopyStep from '../CardCopyStep'; import styles from './ActionsStep.module.scss'; @@ -22,6 +23,7 @@ const StepTypes = { EDIT_STOPWATCH: 'EDIT_STOPWATCH', MOVE: 'MOVE', DELETE: 'DELETE', + COPY: 'COPY', }; const ActionsStep = React.memo( @@ -47,6 +49,7 @@ const ActionsStep = React.memo( onLabelMove, onLabelDelete, onClose, + onCopyCard, }) => { const [t] = useTranslation(); const [step, openStep, handleBack] = useSteps(); @@ -76,6 +79,10 @@ const ActionsStep = React.memo( openStep(StepTypes.MOVE); }, [openStep]); + const handleCopyClick = useCallback(() => { + openStep(StepTypes.COPY); + }, [openStep]); + const handleDeleteClick = useCallback(() => { openStep(StepTypes.DELETE); }, [openStep]); @@ -108,6 +115,7 @@ const ActionsStep = React.memo( onUserSelect={onUserAdd} onUserDeselect={onUserRemove} onBack={handleBack} + onCopyCard={onCopyCard} /> ); case StepTypes.LABELS: @@ -122,6 +130,7 @@ const ActionsStep = React.memo( onMove={onLabelMove} onDelete={onLabelDelete} onBack={handleBack} + onCopyCard={onCopyCard} /> ); case StepTypes.EDIT_DUE_DATE: @@ -131,6 +140,7 @@ const ActionsStep = React.memo( onUpdate={handleDueDateUpdate} onBack={handleBack} onClose={onClose} + onCopyCard={onCopyCard} /> ); case StepTypes.EDIT_STOPWATCH: @@ -140,6 +150,7 @@ const ActionsStep = React.memo( onUpdate={handleStopwatchUpdate} onBack={handleBack} onClose={onClose} + onCopyCard={onCopyCard} /> ); case StepTypes.MOVE: @@ -152,6 +163,7 @@ const ActionsStep = React.memo( onBoardFetch={onBoardFetch} onBack={handleBack} onClose={onClose} + onCopyCard={onCopyCard} /> ); case StepTypes.DELETE: @@ -162,6 +174,20 @@ const ActionsStep = React.memo( buttonContent="action.deleteCard" onConfirm={onDelete} onBack={handleBack} + onCopyCard={onCopyCard} + /> + ); + case StepTypes.COPY: + return ( + ); default: @@ -212,6 +238,11 @@ const ActionsStep = React.memo( context: 'title', })} + + {t('action.copyCard', { + context: 'title', + })} + @@ -243,6 +274,7 @@ ActionsStep.propTypes = { onLabelMove: PropTypes.func.isRequired, onLabelDelete: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired, + onCopyCard: PropTypes.func.isRequired, }; export default ActionsStep; diff --git a/client/src/components/Card/Card.jsx b/client/src/components/Card/Card.jsx index 88d87a0..6463e0e 100755 --- a/client/src/components/Card/Card.jsx +++ b/client/src/components/Card/Card.jsx @@ -51,6 +51,7 @@ const Card = React.memo( onLabelUpdate, onLabelMove, onLabelDelete, + onCopyCard, }) => { const nameEdit = useRef(null); @@ -195,6 +196,7 @@ const Card = React.memo( onLabelUpdate={onLabelUpdate} onLabelMove={onLabelMove} onLabelDelete={onLabelDelete} + onCopyCard={onCopyCard} >
@@ -308,10 +318,18 @@ const CardModal = React.memo( defaultValue={stopwatch} onUpdate={handleStopwatchUpdate} > - + ) : ( - + )} {canEdit && ( @@ -337,7 +355,11 @@ const CardModal = React.memo(
{t('common.description')}
{canEdit ? ( - + {description ? ( - + - + - +