From 44a3c2a2ec7a5d744709a6e0cc05a7d656cbd263 Mon Sep 17 00:00:00 2001 From: Jens Frost <93131870+jensfrost@users.noreply.github.com> Date: Fri, 28 Apr 2023 14:53:47 +0200 Subject: [PATCH 01/17] Added sorting of lists. Added sorting for name, id, position, createdAt, updatedAt, dueDate, creatorUserId --- client/src/actions/lists.js | 31 ++++ client/src/components/Card/Card.jsx | 2 + client/src/components/List/ActionsStep.jsx | 136 +++++++++------ client/src/components/List/List.jsx | 17 +- client/src/components/SortStep/SortStep.jsx | 164 ++++++++++++++++++ .../components/SortStep/SortStep.module.scss | 7 + client/src/components/SortStep/index.js | 3 + client/src/constants/ActionTypes.js | 4 + client/src/constants/EntryActionTypes.js | 1 + client/src/containers/BoardsContainer.js | 1 + client/src/containers/ListContainer.js | 1 + client/src/entry-actions/lists.js | 8 + client/src/locales/sv/core.js | 10 ++ client/src/models/List.js | 65 ++++++- client/src/sagas/core/services/lists.js | 18 ++ client/src/sagas/core/watchers/lists.js | 3 + client/src/sagas/core/watchers/socket.js | 6 + package-lock.json | 12 +- 18 files changed, 424 insertions(+), 65 deletions(-) create mode 100644 client/src/components/SortStep/SortStep.jsx create mode 100644 client/src/components/SortStep/SortStep.module.scss create mode 100644 client/src/components/SortStep/index.js diff --git a/client/src/actions/lists.js b/client/src/actions/lists.js index 59f944f..d48bbcf 100644 --- a/client/src/actions/lists.js +++ b/client/src/actions/lists.js @@ -89,6 +89,35 @@ const handleListDelete = (list) => ({ }, }); +const sortList = (id) => ({ + type: ActionTypes.LIST_SORT, + payload: { + id, + }, +}); + +sortList.success = (list) => ({ + type: ActionTypes.LIST_SORT__SUCCESS, + payload: { + list, + }, +}); + +sortList.failure = (id, error) => ({ + type: ActionTypes.LIST_SORT__FAILURE, + payload: { + id, + error, + }, +}); + +const handleListSort = (list) => ({ + type: ActionTypes.LIST_SORT_HANDLE, + payload: { + list, + }, +}); + export default { createList, handleListCreate, @@ -96,4 +125,6 @@ export default { handleListUpdate, deleteList, handleListDelete, + sortList, + handleListSort, }; diff --git a/client/src/components/Card/Card.jsx b/client/src/components/Card/Card.jsx index 37521a0..88d87a0 100755 --- a/client/src/components/Card/Card.jsx +++ b/client/src/components/Card/Card.jsx @@ -248,6 +248,8 @@ Card.propTypes = { onLabelUpdate: PropTypes.func.isRequired, onLabelMove: PropTypes.func.isRequired, onLabelDelete: PropTypes.func.isRequired, + // onSortTitleAsc: PropTypes.func.isRequired, + // onSortTitleDesc: PropTypes.func.isRequired, }; Card.defaultProps = { diff --git a/client/src/components/List/ActionsStep.jsx b/client/src/components/List/ActionsStep.jsx index 1e94d5a..b894339 100755 --- a/client/src/components/List/ActionsStep.jsx +++ b/client/src/components/List/ActionsStep.jsx @@ -6,78 +6,108 @@ import { Popup } from '../../lib/custom-ui'; import { useSteps } from '../../hooks'; import DeleteStep from '../DeleteStep'; +import SortStep from '../SortStep'; import styles from './ActionsStep.module.scss'; const StepTypes = { DELETE: 'DELETE', + SORT: 'SORT', }; -const ActionsStep = React.memo(({ onNameEdit, onCardAdd, onDelete, onClose }) => { - const [t] = useTranslation(); - const [step, openStep, handleBack] = useSteps(); +const ActionsStep = React.memo( + ({ onNameEdit, onCardAdd, onDelete, onClose, onSort, selectedOption, setSelectedOption }) => { + const [t] = useTranslation(); + const [step, openStep, handleBack] = useSteps(); - const handleEditNameClick = useCallback(() => { - onNameEdit(); - onClose(); - }, [onNameEdit, onClose]); + const handleEditNameClick = useCallback(() => { + onNameEdit(); + onClose(); + }, [onNameEdit, onClose]); - const handleAddCardClick = useCallback(() => { - onCardAdd(); - onClose(); - }, [onCardAdd, onClose]); + const handleAddCardClick = useCallback(() => { + onCardAdd(); + onClose(); + }, [onCardAdd, onClose]); - const handleDeleteClick = useCallback(() => { - openStep(StepTypes.DELETE); - }, [openStep]); + const handleDeleteClick = useCallback(() => { + openStep(StepTypes.DELETE); + }, [openStep]); + + const handleSortClick = useCallback(() => { + openStep(StepTypes.SORT); + }, [openStep]); + + if (step && step.type === StepTypes.DELETE) { + return ( + + ); + } + + if (step && step.type === StepTypes.SORT) { + return ( + + ); + } - if (step && step.type === StepTypes.DELETE) { return ( - + <> + + {t('common.listActions', { + context: 'title', + })} + + + + + {t('action.editTitle', { + context: 'title', + })} + + + {t('action.addCard', { + context: 'title', + })} + + + {t('action.deleteList', { + context: 'title', + })} + + + {t('action.sortList', { + context: 'title', + })} + + + + ); - } - - return ( - <> - - {t('common.listActions', { - context: 'title', - })} - - - - - {t('action.editTitle', { - context: 'title', - })} - - - {t('action.addCard', { - context: 'title', - })} - - - {t('action.deleteList', { - context: 'title', - })} - - - - - ); -}); + }, +); ActionsStep.propTypes = { onNameEdit: PropTypes.func.isRequired, onCardAdd: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired, + onSort: PropTypes.func.isRequired, + selectedOption: PropTypes.string.isRequired, + setSelectedOption: PropTypes.func.isRequired, }; export default ActionsStep; diff --git a/client/src/components/List/List.jsx b/client/src/components/List/List.jsx index f09116c..dd140fb 100755 --- a/client/src/components/List/List.jsx +++ b/client/src/components/List/List.jsx @@ -4,7 +4,7 @@ import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; import { Draggable, Droppable } from 'react-beautiful-dnd'; import { Button, Icon } from 'semantic-ui-react'; -import { usePopup } from '../../lib/popup'; +import { usePopup, closePopup } from '../../lib/popup'; import DroppableTypes from '../../constants/DroppableTypes'; import CardContainer from '../../containers/CardContainer'; @@ -19,6 +19,7 @@ const List = React.memo( ({ id, index, name, isPersisted, cardIds, canEdit, onUpdate, onDelete, onCardCreate }) => { const [t] = useTranslation(); const [isAddCardOpened, setIsAddCardOpened] = useState(false); + const [selectedOption, setSelectedOption] = useState('name'); const nameEdit = useRef(null); const listWrapper = useRef(null); @@ -40,11 +41,11 @@ const List = React.memo( const handleAddCardClick = useCallback(() => { setIsAddCardOpened(true); - }, []); + }, [setIsAddCardOpened]); const handleAddCardClose = useCallback(() => { setIsAddCardOpened(false); - }, []); + }, [setIsAddCardOpened]); const handleNameEdit = useCallback(() => { nameEdit.current.open(); @@ -52,7 +53,12 @@ const List = React.memo( const handleCardAdd = useCallback(() => { setIsAddCardOpened(true); - }, []); + }, [setIsAddCardOpened]); + + const onSort = useCallback(() => { + onUpdate({ selectedOption: document.querySelector('input[name="sort"]:checked').value }); + closePopup(); + }, [onUpdate]); useEffect(() => { if (isAddCardOpened) { @@ -114,6 +120,9 @@ const List = React.memo( onNameEdit={handleNameEdit} onCardAdd={handleCardAdd} onDelete={onDelete} + onSort={onSort} + selectedOption={selectedOption} + setSelectedOption={setSelectedOption} > + + + after connection restored', + areYouSureYouWantToCopyThisCard: 'Are you sure you want to copy this card', areYouSureYouWantToDeleteThisAttachment: 'Are you sure you want to delete this attachment?', areYouSureYouWantToDeleteThisBoard: 'Are you sure you want to delete this board?', areYouSureYouWantToDeleteThisCard: 'Are you sure you want to delete this card?', areYouSureYouWantToDeleteThisComment: 'Are you sure you want to delete this comment?', areYouSureYouWantToDeleteThisLabel: 'Are you sure you want to delete this label?', areYouSureYouWantToDeleteThisList: 'Are you sure you want to delete this list?', - areYouSureYouWantToSortThisList: 'Are you sure you want to sort this list?', areYouSureYouWantToDeleteThisProject: 'Are you sure you want to delete this project?', areYouSureYouWantToDeleteThisTask: 'Are you sure you want to delete this task?', areYouSureYouWantToDeleteThisUser: 'Are you sure you want to delete this user?', @@ -37,6 +37,7 @@ export default { 'Are you sure you want to remove this manager from the project?', areYouSureYouWantToRemoveThisMemberFromBoard: 'Are you sure you want to remove this member from the board?', + areYouSureYouWantToSortThisList: 'Are you sure you want to sort this list?', attachment: 'Attachment', attachments: 'Attachments', authentication: 'Authentication', @@ -50,6 +51,7 @@ export default { cardNotFound_title: 'Card Not Found', cardOrActionAreDeleted: 'Card or action are deleted', color: 'Color', + copyCard: 'Copy card', createBoard_title: 'Create Board', createLabel_title: 'Create Label', createNewOneOrSelectExistingOne: 'Create a new one or select
an existing one', @@ -175,6 +177,8 @@ export default { addTask: 'Add task', addToCard: 'Add to card', addUser: 'Add user', + copy: 'Copy', + copyCard: 'Copy card', createBoard: 'Create board', createFile: 'Create file', createLabel: 'Create label', diff --git a/client/src/locales/sv/core.js b/client/src/locales/sv/core.js index 8478d03..6fea429 100644 --- a/client/src/locales/sv/core.js +++ b/client/src/locales/sv/core.js @@ -24,6 +24,7 @@ export default { all: 'Alla', allChangesWillBeAutomaticallySavedAfterConnectionRestored: 'Alla ändringar kommer att sparas automatiskt
så fort anslutningen är återställd', + areYouSureYouWantToCopyThisCard: 'Är du säker på att du vill kopiera det här kortet', areYouSureYouWantToDeleteThisAttachment: 'Är du säker på att du vill ta bort den här bilagan?', areYouSureYouWantToDeleteThisBoard: 'Är du säker på att du vill ta bort den här tavlan?', @@ -52,6 +53,7 @@ export default { cardNotFound_title: 'Kort Ej Funnet', cardOrActionAreDeleted: 'Kort eller åtgärd är borttagen', color: 'Färg', + copyCard: 'Kopiera kort', createBoard_title: 'Skapa Tavla', createLabel_title: 'Skapa Etikett', createNewOneOrSelectExistingOne: 'Skapa en ny eller välj
en redan existerande', @@ -162,6 +164,8 @@ export default { addTask: 'Lägg till uppgift', addToCard: 'Lägg till i kort', addUser: 'Lägg till användare', + copy: 'Kopiera', + copyCard: 'Kopiera kort', createBoard: 'Skapa tavla', createFile: 'Skapa fil', createLabel: 'Skapa etikett', From 21fc0f560a435ab9eefb11c074387a3aad770909 Mon Sep 17 00:00:00 2001 From: Jens Frost <93131870+jensfrost@users.noreply.github.com> Date: Tue, 16 May 2023 16:44:47 +0200 Subject: [PATCH 04/17] =?UTF-8?q?Add=C3=ADng=20code=20where=20copying=20fr?= =?UTF-8?q?om=20list=20works=20but=20from=20opened=20card=20does=20not.=20?= =?UTF-8?q?Copying=20content=20on=20card=20does=20not=20work=20from=20any?= =?UTF-8?q?=20place.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/actions/cards.js | 31 +++ .../src/components/BoardActions/Filters.jsx | 3 + client/src/components/Boards/Boards.jsx | 198 +++++++++--------- client/src/components/Card/ActionsStep.jsx | 32 +++ client/src/components/Card/Card.jsx | 3 + client/src/components/CardCopyPopup.jsx | 5 + .../components/CardCopyStep/CardCopyStep.jsx | 169 +++++++++++++++ .../CardCopyStep/CardCopyStep.module.scss | 12 ++ client/src/components/CardCopyStep/index.js | 3 + client/src/components/CardModal/CardModal.jsx | 58 ++++- .../components/CardMoveStep/CardMoveStep.jsx | 14 +- .../src/components/LabelsStep/LabelsStep.jsx | 5 + client/src/components/List/List.jsx | 16 +- client/src/constants/ActionTypes.js | 2 + client/src/constants/EntryActionTypes.js | 2 + client/src/constants/Enums.js | 1 + client/src/containers/BoardContainer.js | 1 + client/src/containers/BoardsContainer.js | 1 + client/src/containers/CardContainer.js | 1 + client/src/containers/CardModalContainer.js | 1 + client/src/entry-actions/cards.js | 10 + client/src/lib/popup/with-popup.jsx | 109 ++++++++++ client/src/sagas/core/watchers/cards.js | 4 + server/api/models/Action.js | 1 + 24 files changed, 573 insertions(+), 109 deletions(-) create mode 100644 client/src/components/CardCopyPopup.jsx create mode 100644 client/src/components/CardCopyStep/CardCopyStep.jsx create mode 100644 client/src/components/CardCopyStep/CardCopyStep.module.scss create mode 100644 client/src/components/CardCopyStep/index.js create mode 100644 client/src/lib/popup/with-popup.jsx 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 ? ( - + - + - + - - )} - - ) : ( - // eslint-disable-next-line react/jsx-props-no-spreading - + const itemsNode = items.map((item, index) => ( + + {({ innerRef, draggableProps, dragHandleProps }) => ( + // eslint-disable-next-line react/jsx-props-no-spreading +
+
+ {item.isPersisted ? ( + <> + {item.name} - - )} -
+ + {canEdit && ( + handleUpdate(item.id, data)} + onDelete={() => handleDelete(item.id)} + > + + + )} + + ) : ( + // 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 @@ -135,7 +132,6 @@ 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 4dd97de..f1401ce 100644 --- a/client/src/components/Card/ActionsStep.jsx +++ b/client/src/components/Card/ActionsStep.jsx @@ -132,7 +132,6 @@ const ActionsStep = React.memo( onUserSelect={onUserAdd} onUserDeselect={onUserRemove} onBack={handleBack} - onCopyCard={onCopyCard} /> ); case StepTypes.LABELS: @@ -147,7 +146,6 @@ const ActionsStep = React.memo( onMove={onLabelMove} onDelete={onLabelDelete} onBack={handleBack} - onCopyCard={onCopyCard} /> ); case StepTypes.EDIT_DUE_DATE: @@ -157,7 +155,6 @@ const ActionsStep = React.memo( onUpdate={handleDueDateUpdate} onBack={handleBack} onClose={onClose} - onCopyCard={onCopyCard} /> ); case StepTypes.EDIT_STOPWATCH: @@ -167,7 +164,6 @@ const ActionsStep = React.memo( onUpdate={handleStopwatchUpdate} onBack={handleBack} onClose={onClose} - onCopyCard={onCopyCard} /> ); case StepTypes.MOVE: @@ -180,7 +176,6 @@ const ActionsStep = React.memo( onBoardFetch={onBoardFetch} onBack={handleBack} onClose={onClose} - onCopyCard={onCopyCard} /> ); case StepTypes.DELETE: @@ -191,7 +186,6 @@ const ActionsStep = React.memo( buttonContent="action.deleteCard" onConfirm={onDelete} onBack={handleBack} - onCopyCard={onCopyCard} /> ); case StepTypes.COPY: diff --git a/client/src/components/CardModal/CardModal.jsx b/client/src/components/CardModal/CardModal.jsx index eadcd8c..a6f885f 100755 --- a/client/src/components/CardModal/CardModal.jsx +++ b/client/src/components/CardModal/CardModal.jsx @@ -259,7 +259,6 @@ const CardModal = React.memo( currentUserIds={userIds} onUserSelect={onUserAdd} onUserDeselect={onUserRemove} - onCopyCard={onCopyCard} > @@ -274,7 +273,6 @@ const CardModal = React.memo( currentUserIds={userIds} onUserSelect={onUserAdd} onUserDeselect={onUserRemove} - onCopyCard={onCopyCard} >
@@ -372,18 +364,10 @@ const CardModal = React.memo( defaultValue={stopwatch} onUpdate={handleStopwatchUpdate} > - +
) : ( - + )} {canEdit && ( @@ -409,11 +393,7 @@ const CardModal = React.memo(
{t('common.description')}
{canEdit ? ( - + {description ? ( - + - + - +