mirror of
https://github.com/plankanban/planka.git
synced 2025-08-05 13:35:27 +02:00
feat: Move infrequent card actions to more actions menu
This commit is contained in:
parent
df023439c1
commit
6dfb5ba024
29 changed files with 253 additions and 156 deletions
153
client/src/components/cards/CardModal/MoreActionsStep.jsx
Normal file
153
client/src/components/cards/CardModal/MoreActionsStep.jsx
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Icon, Menu } from 'semantic-ui-react';
|
||||
import { Popup } from '../../../lib/custom-ui';
|
||||
|
||||
import selectors from '../../../selectors';
|
||||
import entryActions from '../../../entry-actions';
|
||||
import { useSteps } from '../../../hooks';
|
||||
import { isListArchiveOrTrash } from '../../../utils/record-helpers';
|
||||
import { BoardMembershipRoles } from '../../../constants/Enums';
|
||||
import SelectCardTypeStep from '../SelectCardTypeStep';
|
||||
import MoveCardStep from '../MoveCardStep';
|
||||
|
||||
import styles from './MoreActionsStep.module.scss';
|
||||
|
||||
const StepTypes = {
|
||||
EDIT_TYPE: 'EDIT_TYPE',
|
||||
MOVE: 'MOVE',
|
||||
};
|
||||
|
||||
const MoreActionsStep = React.memo(({ onClose }) => {
|
||||
const selectListById = useMemo(() => selectors.makeSelectListById(), []);
|
||||
|
||||
const card = useSelector(selectors.selectCurrentCard);
|
||||
const board = useSelector(selectors.selectCurrentBoard);
|
||||
|
||||
const { canEditType, canDuplicate, canMove } = useSelector((state) => {
|
||||
const list = selectListById(state, card.listId);
|
||||
|
||||
if (isListArchiveOrTrash(list)) {
|
||||
return {
|
||||
canEditType: false,
|
||||
canDuplicate: false,
|
||||
canMove: false,
|
||||
};
|
||||
}
|
||||
|
||||
const boardMembership = selectors.selectCurrentUserMembershipForCurrentBoard(state);
|
||||
const isEditor = !!boardMembership && boardMembership.role === BoardMembershipRoles.EDITOR;
|
||||
|
||||
return {
|
||||
canEditType: isEditor,
|
||||
canDuplicate: isEditor,
|
||||
canMove: isEditor,
|
||||
};
|
||||
}, shallowEqual);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const [t] = useTranslation();
|
||||
const [step, openStep, handleBack] = useSteps();
|
||||
|
||||
const handleTypeSelect = useCallback(
|
||||
(type) => {
|
||||
dispatch(
|
||||
entryActions.updateCurrentCard({
|
||||
type,
|
||||
}),
|
||||
);
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const handleDuplicateClick = useCallback(() => {
|
||||
dispatch(
|
||||
entryActions.duplicateCurrentCard({
|
||||
name: `${card.name} (${t('common.copy', {
|
||||
context: 'inline',
|
||||
})})`,
|
||||
}),
|
||||
);
|
||||
|
||||
onClose();
|
||||
}, [onClose, card.name, dispatch, t]);
|
||||
|
||||
const handleEditTypeClick = useCallback(() => {
|
||||
openStep(StepTypes.EDIT_TYPE);
|
||||
}, [openStep]);
|
||||
|
||||
const handleMoveClick = useCallback(() => {
|
||||
openStep(StepTypes.MOVE);
|
||||
}, [openStep]);
|
||||
|
||||
if (step) {
|
||||
switch (step.type) {
|
||||
case StepTypes.EDIT_TYPE:
|
||||
return (
|
||||
<SelectCardTypeStep
|
||||
withButton
|
||||
defaultValue={card.type}
|
||||
title="common.editType"
|
||||
buttonContent="action.save"
|
||||
onSelect={handleTypeSelect}
|
||||
onBack={handleBack}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
case StepTypes.MOVE:
|
||||
return <MoveCardStep id={card.id} onBack={handleBack} onClose={onClose} />;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Popup.Header>
|
||||
{t('common.moreActions', {
|
||||
context: 'title',
|
||||
})}
|
||||
</Popup.Header>
|
||||
<Popup.Content>
|
||||
<Menu secondary vertical className={styles.menu}>
|
||||
{!board.limitCardTypesToDefaultOne && canEditType && (
|
||||
<Menu.Item className={styles.menuItem} onClick={handleEditTypeClick}>
|
||||
<Icon name="map outline" className={styles.menuItemIcon} />
|
||||
{t('action.editType', {
|
||||
context: 'title',
|
||||
})}
|
||||
</Menu.Item>
|
||||
)}
|
||||
{canDuplicate && (
|
||||
<Menu.Item className={styles.menuItem} onClick={handleDuplicateClick}>
|
||||
<Icon name="copy outline" className={styles.menuItemIcon} />
|
||||
{t('action.duplicateCard', {
|
||||
context: 'title',
|
||||
})}
|
||||
</Menu.Item>
|
||||
)}
|
||||
{canMove && (
|
||||
<Menu.Item className={styles.menuItem} onClick={handleMoveClick}>
|
||||
<Icon name="share square outline" className={styles.menuItemIcon} />
|
||||
{t('action.moveCard', {
|
||||
context: 'title',
|
||||
})}
|
||||
</Menu.Item>
|
||||
)}
|
||||
</Menu>
|
||||
</Popup.Content>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
MoreActionsStep.propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default MoreActionsStep;
|
|
@ -0,0 +1,21 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
:global(#app) {
|
||||
.menu {
|
||||
margin: -7px -12px -5px;
|
||||
width: calc(100% + 24px);
|
||||
}
|
||||
|
||||
.menuItem {
|
||||
margin: 0;
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
.menuItemIcon {
|
||||
float: left;
|
||||
margin: 0 0.5em 0 0;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback, useContext, useMemo, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
@ -24,12 +23,11 @@ import TaskLists from './TaskLists';
|
|||
import CustomFieldGroups from './CustomFieldGroups';
|
||||
import Communication from './Communication';
|
||||
import CreationDetailsStep from './CreationDetailsStep';
|
||||
import MoreActionsStep from './MoreActionsStep';
|
||||
import DueDateChip from '../DueDateChip';
|
||||
import StopwatchChip from '../StopwatchChip';
|
||||
import SelectCardTypeStep from '../SelectCardTypeStep';
|
||||
import EditDueDateStep from '../EditDueDateStep';
|
||||
import EditStopwatchStep from '../EditStopwatchStep';
|
||||
import MoveCardStep from '../MoveCardStep';
|
||||
import ExpandableMarkdown from '../../common/ExpandableMarkdown';
|
||||
import EditMarkdown from '../../common/EditMarkdown';
|
||||
import ConfirmationStep from '../../common/ConfirmationStep';
|
||||
|
@ -45,7 +43,7 @@ import AddCustomFieldGroupStep from '../../custom-field-groups/AddCustomFieldGro
|
|||
|
||||
import styles from './ProjectContent.module.scss';
|
||||
|
||||
const ProjectContent = React.memo(({ onClose }) => {
|
||||
const ProjectContent = React.memo(() => {
|
||||
const selectListById = useMemo(() => selectors.makeSelectListById(), []);
|
||||
const selectPrevListById = useMemo(() => selectors.makeSelectListById(), []);
|
||||
|
||||
|
@ -155,17 +153,6 @@ const ProjectContent = React.memo(({ onClose }) => {
|
|||
[dispatch],
|
||||
);
|
||||
|
||||
const handleTypeSelect = useCallback(
|
||||
(type) => {
|
||||
dispatch(
|
||||
entryActions.updateCurrentCard({
|
||||
type,
|
||||
}),
|
||||
);
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const handleNameUpdate = useCallback(
|
||||
(name) => {
|
||||
dispatch(
|
||||
|
@ -198,18 +185,6 @@ const ProjectContent = React.memo(({ onClose }) => {
|
|||
);
|
||||
}, [card.stopwatch, dispatch]);
|
||||
|
||||
const handleDuplicateClick = useCallback(() => {
|
||||
dispatch(
|
||||
entryActions.duplicateCurrentCard({
|
||||
name: `${card.name} (${t('common.copy', {
|
||||
context: 'inline',
|
||||
})})`,
|
||||
}),
|
||||
);
|
||||
|
||||
onClose();
|
||||
}, [onClose, card.name, dispatch, t]);
|
||||
|
||||
const handleRestoreClick = useCallback(() => {
|
||||
dispatch(entryActions.moveCurrentCard(card.prevListId, undefined, true));
|
||||
}, [card.prevListId, dispatch]);
|
||||
|
@ -304,13 +279,12 @@ const ProjectContent = React.memo(({ onClose }) => {
|
|||
const BoardMembershipsPopup = usePopupInClosableContext(BoardMembershipsStep);
|
||||
const LabelsPopup = usePopupInClosableContext(LabelsStep);
|
||||
const ListsPopup = usePopupInClosableContext(ListsStep);
|
||||
const SelectCardTypePopup = usePopupInClosableContext(SelectCardTypeStep);
|
||||
const EditDueDatePopup = usePopupInClosableContext(EditDueDateStep);
|
||||
const EditStopwatchPopup = usePopupInClosableContext(EditStopwatchStep);
|
||||
const AddTaskListPopup = usePopupInClosableContext(AddTaskListStep);
|
||||
const AddAttachmentPopup = usePopupInClosableContext(AddAttachmentStep);
|
||||
const AddCustomFieldGroupPopup = usePopupInClosableContext(AddCustomFieldGroupStep);
|
||||
const MoveCardPopup = usePopupInClosableContext(MoveCardStep);
|
||||
const MoreActionsPopup = usePopupInClosableContext(MoreActionsStep);
|
||||
const ConfirmationPopup = usePopupInClosableContext(ConfirmationStep);
|
||||
|
||||
return (
|
||||
|
@ -706,40 +680,6 @@ const ProjectContent = React.memo(({ onClose }) => {
|
|||
)}
|
||||
</Button>
|
||||
)}
|
||||
{!board.limitCardTypesToDefaultOne && canEditType && (
|
||||
<SelectCardTypePopup
|
||||
withButton
|
||||
defaultValue={card.type}
|
||||
title="common.editType"
|
||||
buttonContent="action.save"
|
||||
onSelect={handleTypeSelect}
|
||||
>
|
||||
<Button fluid className={classNames(styles.actionButton, styles.hidable)}>
|
||||
<Icon name="map outline" className={styles.actionIcon} />
|
||||
{t('action.editType', {
|
||||
context: 'title',
|
||||
})}
|
||||
</Button>
|
||||
</SelectCardTypePopup>
|
||||
)}
|
||||
{canDuplicate && (
|
||||
<Button
|
||||
fluid
|
||||
className={classNames(styles.actionButton, styles.hidable)}
|
||||
onClick={handleDuplicateClick}
|
||||
>
|
||||
<Icon name="copy outline" className={styles.actionIcon} />
|
||||
{t('action.duplicate')}
|
||||
</Button>
|
||||
)}
|
||||
{canMove && (
|
||||
<MoveCardPopup id={card.id}>
|
||||
<Button fluid className={classNames(styles.actionButton, styles.hidable)}>
|
||||
<Icon name="share square outline" className={styles.actionIcon} />
|
||||
{t('action.move')}
|
||||
</Button>
|
||||
</MoveCardPopup>
|
||||
)}
|
||||
{canRestore && (isInArchiveList || isInTrashList) && (
|
||||
<Button
|
||||
fluid
|
||||
|
@ -789,6 +729,16 @@ const ProjectContent = React.memo(({ onClose }) => {
|
|||
</Button>
|
||||
</ConfirmationPopup>
|
||||
)}
|
||||
{((!board.limitCardTypesToDefaultOne && canEditType) ||
|
||||
canDuplicate ||
|
||||
canMove) && (
|
||||
<MoreActionsPopup>
|
||||
<Button fluid className={classNames(styles.moreActionsButton, styles.hidable)}>
|
||||
<Icon name="ellipsis horizontal" className={styles.moreActionsButtonIcon} />
|
||||
{t('common.moreActions')}
|
||||
</Button>
|
||||
</MoreActionsPopup>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -798,8 +748,4 @@ const ProjectContent = React.memo(({ onClose }) => {
|
|||
);
|
||||
});
|
||||
|
||||
ProjectContent.propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default ProjectContent;
|
||||
|
|
|
@ -260,6 +260,28 @@
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.moreActionsButton {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
color: #6b808c;
|
||||
font-weight: normal;
|
||||
margin-top: 8px;
|
||||
padding: 6px 8px 6px 18px;
|
||||
text-align: left;
|
||||
text-decoration: underline;
|
||||
transition: none;
|
||||
|
||||
&:hover {
|
||||
background: rgba(9, 30, 66, 0.08);
|
||||
color: #092d42;
|
||||
}
|
||||
}
|
||||
|
||||
.moreActionsButtonIcon {
|
||||
margin-right: 8px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidebarPadding {
|
||||
padding: 8px 16px 8px 8px;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback, useContext, useMemo, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
@ -24,8 +23,7 @@ import NameField from '../NameField';
|
|||
import CustomFieldGroups from '../CustomFieldGroups';
|
||||
import Communication from '../Communication';
|
||||
import CreationDetailsStep from '../CreationDetailsStep';
|
||||
import SelectCardTypeStep from '../../SelectCardTypeStep';
|
||||
import MoveCardStep from '../../MoveCardStep';
|
||||
import MoreActionsStep from '../MoreActionsStep';
|
||||
import Markdown from '../../../common/Markdown';
|
||||
import EditMarkdown from '../../../common/EditMarkdown';
|
||||
import ConfirmationStep from '../../../common/ConfirmationStep';
|
||||
|
@ -40,7 +38,7 @@ import AddCustomFieldGroupStep from '../../../custom-field-groups/AddCustomField
|
|||
|
||||
import styles from './StoryContent.module.scss';
|
||||
|
||||
const StoryContent = React.memo(({ onClose }) => {
|
||||
const StoryContent = React.memo(() => {
|
||||
const selectListById = useMemo(() => selectors.makeSelectListById(), []);
|
||||
const selectPrevListById = useMemo(() => selectors.makeSelectListById(), []);
|
||||
const selectAttachmentById = useMemo(() => selectors.makeSelectAttachmentById(), []);
|
||||
|
@ -150,17 +148,6 @@ const StoryContent = React.memo(({ onClose }) => {
|
|||
[dispatch],
|
||||
);
|
||||
|
||||
const handleTypeSelect = useCallback(
|
||||
(type) => {
|
||||
dispatch(
|
||||
entryActions.updateCurrentCard({
|
||||
type,
|
||||
}),
|
||||
);
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const handleNameUpdate = useCallback(
|
||||
(name) => {
|
||||
dispatch(
|
||||
|
@ -183,18 +170,6 @@ const StoryContent = React.memo(({ onClose }) => {
|
|||
[dispatch],
|
||||
);
|
||||
|
||||
const handleDuplicateClick = useCallback(() => {
|
||||
dispatch(
|
||||
entryActions.duplicateCurrentCard({
|
||||
name: `${card.name} (${t('common.copy', {
|
||||
context: 'inline',
|
||||
})})`,
|
||||
}),
|
||||
);
|
||||
|
||||
onClose();
|
||||
}, [onClose, card.name, dispatch, t]);
|
||||
|
||||
const handleRestoreClick = useCallback(() => {
|
||||
dispatch(entryActions.moveCurrentCard(card.prevListId, undefined, true));
|
||||
}, [card.prevListId, dispatch]);
|
||||
|
@ -300,10 +275,9 @@ const StoryContent = React.memo(({ onClose }) => {
|
|||
const BoardMembershipsPopup = usePopupInClosableContext(BoardMembershipsStep);
|
||||
const LabelsPopup = usePopupInClosableContext(LabelsStep);
|
||||
const ListsPopup = usePopupInClosableContext(ListsStep);
|
||||
const SelectCardTypePopup = usePopupInClosableContext(SelectCardTypeStep);
|
||||
const AddAttachmentPopup = usePopupInClosableContext(AddAttachmentStep);
|
||||
const AddCustomFieldGroupPopup = usePopupInClosableContext(AddCustomFieldGroupStep);
|
||||
const MoveCardPopup = usePopupInClosableContext(MoveCardStep);
|
||||
const MoreActionsPopup = usePopupInClosableContext(MoreActionsStep);
|
||||
const ConfirmationPopup = usePopupInClosableContext(ConfirmationStep);
|
||||
|
||||
return (
|
||||
|
@ -614,40 +588,6 @@ const StoryContent = React.memo(({ onClose }) => {
|
|||
)}
|
||||
</Button>
|
||||
)}
|
||||
{!board.limitCardTypesToDefaultOne && canEditType && (
|
||||
<SelectCardTypePopup
|
||||
withButton
|
||||
defaultValue={card.type}
|
||||
title="common.editType"
|
||||
buttonContent="action.save"
|
||||
onSelect={handleTypeSelect}
|
||||
>
|
||||
<Button fluid className={classNames(styles.actionButton, styles.hidable)}>
|
||||
<Icon name="map outline" className={styles.actionIcon} />
|
||||
{t('action.editType', {
|
||||
context: 'title',
|
||||
})}
|
||||
</Button>
|
||||
</SelectCardTypePopup>
|
||||
)}
|
||||
{canDuplicate && (
|
||||
<Button
|
||||
fluid
|
||||
className={classNames(styles.actionButton, styles.hidable)}
|
||||
onClick={handleDuplicateClick}
|
||||
>
|
||||
<Icon name="copy outline" className={styles.actionIcon} />
|
||||
{t('action.duplicate')}
|
||||
</Button>
|
||||
)}
|
||||
{canMove && (
|
||||
<MoveCardPopup id={card.id}>
|
||||
<Button fluid className={classNames(styles.actionButton, styles.hidable)}>
|
||||
<Icon name="share square outline" className={styles.actionIcon} />
|
||||
{t('action.move')}
|
||||
</Button>
|
||||
</MoveCardPopup>
|
||||
)}
|
||||
{canRestore && (isInArchiveList || isInTrashList) && (
|
||||
<Button
|
||||
fluid
|
||||
|
@ -697,6 +637,16 @@ const StoryContent = React.memo(({ onClose }) => {
|
|||
</Button>
|
||||
</ConfirmationPopup>
|
||||
)}
|
||||
{((!board.limitCardTypesToDefaultOne && canEditType) ||
|
||||
canDuplicate ||
|
||||
canMove) && (
|
||||
<MoreActionsPopup>
|
||||
<Button fluid className={classNames(styles.moreActionsButton, styles.hidable)}>
|
||||
<Icon name="ellipsis horizontal" className={styles.moreActionsButtonIcon} />
|
||||
{t('common.moreActions')}
|
||||
</Button>
|
||||
</MoreActionsPopup>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -706,8 +656,4 @@ const StoryContent = React.memo(({ onClose }) => {
|
|||
);
|
||||
});
|
||||
|
||||
StoryContent.propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default StoryContent;
|
||||
|
|
|
@ -286,6 +286,28 @@
|
|||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.moreActionsButton {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
color: #6b808c;
|
||||
font-weight: normal;
|
||||
margin-top: 8px;
|
||||
padding: 6px 8px 6px 18px;
|
||||
text-align: left;
|
||||
text-decoration: underline;
|
||||
transition: none;
|
||||
|
||||
&:hover {
|
||||
background: rgba(9, 30, 66, 0.08);
|
||||
color: #092d42;
|
||||
}
|
||||
}
|
||||
|
||||
.moreActionsButtonIcon {
|
||||
margin-right: 8px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidebarPadding {
|
||||
padding: 8px 16px 8px 8px;
|
||||
|
||||
|
|
|
@ -197,7 +197,6 @@ export default {
|
|||
deleteTask: 'حذف المهمة',
|
||||
deleteTask_title: 'حذف المهمة',
|
||||
deleteUser: 'حذف المستخدم',
|
||||
duplicate: 'تكرار',
|
||||
duplicateCard_title: 'تكرار البطاقة',
|
||||
edit: 'تعديل',
|
||||
editDescription_title: 'تعديل الوصف',
|
||||
|
|
|
@ -202,7 +202,6 @@ export default {
|
|||
deleteTask: 'Изтриване на задача',
|
||||
deleteTask_title: 'Изтриване на задача',
|
||||
deleteUser: 'Изтриване на потребител',
|
||||
duplicate: 'Направи дубликат',
|
||||
duplicateCard_title: 'Дублирана карта',
|
||||
edit: 'Редактиране',
|
||||
editDescription_title: 'Редактиране на описание',
|
||||
|
|
|
@ -354,7 +354,6 @@ export default {
|
|||
deleteUser: 'Smazat uživatele',
|
||||
deleteUser_title: 'Smazat uživatele',
|
||||
dismissAll: 'Vše přečteno',
|
||||
duplicate: 'Duplikovat',
|
||||
duplicateCard_title: 'Duplikovat kartu',
|
||||
edit: 'Upravit',
|
||||
editColor_title: 'Upravit barvu',
|
||||
|
|
|
@ -382,7 +382,6 @@ export default {
|
|||
deleteUser: 'Slet bruger',
|
||||
deleteUser_title: 'Slet bruger',
|
||||
dismissAll: 'Afvis alle',
|
||||
duplicate: 'Duplikér',
|
||||
duplicateCard_title: 'Duplikér kort',
|
||||
edit: 'Rediger',
|
||||
editColor_title: 'Rediger farve',
|
||||
|
|
|
@ -371,7 +371,6 @@ export default {
|
|||
deleteUser: 'Benutzer löschen',
|
||||
deleteUser_title: 'Benutzer löschen',
|
||||
dismissAll: 'Alle verwerfen',
|
||||
duplicate: 'Duplizieren',
|
||||
duplicateCard_title: 'Karte duplizieren',
|
||||
edit: 'Bearbeiten',
|
||||
editColor_title: 'Farbe bearbeiten',
|
||||
|
|
|
@ -398,7 +398,6 @@ export default {
|
|||
deleteUser: 'Διαγραφή χρήστη',
|
||||
deleteUser_title: 'Διαγραφή χρήστη',
|
||||
dismissAll: 'Απόρριψη όλων',
|
||||
duplicate: 'Διπλασιασμός',
|
||||
duplicateCard_title: 'Διπλασιασμός κάρτας',
|
||||
edit: 'Επεξεργασία',
|
||||
editColor_title: 'Επεξεργασία χρώματος',
|
||||
|
|
|
@ -216,6 +216,8 @@ export default {
|
|||
memberActions_title: 'Member Actions',
|
||||
members: 'Members',
|
||||
minutes: 'Minutes',
|
||||
moreActions: 'More actions',
|
||||
moreActions_title: 'More Actions',
|
||||
moveCard_title: 'Move Card',
|
||||
myOwn_title: 'My Own',
|
||||
name: 'Name',
|
||||
|
@ -391,7 +393,6 @@ export default {
|
|||
deleteUser_title: 'Delete User',
|
||||
deleteWebhook: 'Delete webhook',
|
||||
dismissAll: 'Dismiss all',
|
||||
duplicate: 'Duplicate',
|
||||
duplicateCard_title: 'Duplicate Card',
|
||||
edit: 'Edit',
|
||||
editColor_title: 'Edit Color',
|
||||
|
|
|
@ -211,6 +211,8 @@ export default {
|
|||
memberActions_title: 'Member Actions',
|
||||
members: 'Members',
|
||||
minutes: 'Minutes',
|
||||
moreActions: 'More actions',
|
||||
moreActions_title: 'More Actions',
|
||||
moveCard_title: 'Move Card',
|
||||
myOwn_title: 'My Own',
|
||||
name: 'Name',
|
||||
|
@ -386,7 +388,6 @@ export default {
|
|||
deleteUser_title: 'Delete User',
|
||||
deleteWebhook: 'Delete webhook',
|
||||
dismissAll: 'Dismiss all',
|
||||
duplicate: 'Duplicate',
|
||||
duplicateCard_title: 'Duplicate Card',
|
||||
edit: 'Edit',
|
||||
editColor_title: 'Edit Color',
|
||||
|
|
|
@ -374,7 +374,6 @@ export default {
|
|||
deleteUser: 'Borrar usuario',
|
||||
deleteUser_title: 'Borrar Usuario',
|
||||
dismissAll: 'Descartar todo',
|
||||
duplicate: 'Duplicar',
|
||||
duplicateCard_title: 'Duplicar tarjeta',
|
||||
edit: 'Editar',
|
||||
editColor_title: 'Editar color',
|
||||
|
|
|
@ -380,7 +380,6 @@ export default {
|
|||
deleteUser: 'Kustuta kasutaja',
|
||||
deleteUser_title: 'Kustuta kasutaja',
|
||||
dismissAll: 'Eemalda kõik',
|
||||
duplicate: 'Dubleeri',
|
||||
duplicateCard_title: 'Duplikaardi loomine',
|
||||
edit: 'Muuda',
|
||||
editColor_title: 'Muuda värvi',
|
||||
|
|
|
@ -199,7 +199,6 @@ export default {
|
|||
deleteTask: 'حذف وظیفه',
|
||||
deleteTask_title: 'حذف وظیفه',
|
||||
deleteUser: 'حذف کاربر',
|
||||
duplicate: 'تکرار',
|
||||
duplicateCard_title: 'تکرار کارت',
|
||||
edit: 'ویرایش',
|
||||
editDescription_title: 'ویرایش توضیحات',
|
||||
|
|
|
@ -380,7 +380,6 @@ export default {
|
|||
deleteUser: 'Poista käyttäjä',
|
||||
deleteUser_title: 'Poista käyttäjä',
|
||||
dismissAll: 'Sulje kaikki',
|
||||
duplicate: 'Monista',
|
||||
duplicateCard_title: 'Monista kortti',
|
||||
edit: 'Muokkaa',
|
||||
editColor_title: 'Muokkaa väriä',
|
||||
|
|
|
@ -393,7 +393,6 @@ export default {
|
|||
deleteUser_title: 'Supprimer l’utilisateur',
|
||||
deleteWebhook: 'Supprimer le webhook',
|
||||
dismissAll: 'Tout rejeter',
|
||||
duplicate: 'Dupliquer',
|
||||
duplicateCard_title: 'Dupliquer la carte',
|
||||
edit: 'Modifier',
|
||||
editColor_title: 'Modifier la couleur',
|
||||
|
|
|
@ -200,7 +200,6 @@ export default {
|
|||
deleteTask: 'Feladat törlése',
|
||||
deleteTask_title: 'Feladat törlése',
|
||||
deleteUser: 'Felhasználó törlése',
|
||||
duplicate: 'Másolás',
|
||||
duplicateCard_title: 'Kártya másolása',
|
||||
edit: 'Szerkesztés',
|
||||
editDescription_title: 'Leírás szerkesztése',
|
||||
|
|
|
@ -377,7 +377,6 @@ export default {
|
|||
deleteUser: 'Elimina utente',
|
||||
deleteUser_title: 'Elimina utente',
|
||||
dismissAll: 'Ignora tutto',
|
||||
duplicate: 'Duplica',
|
||||
duplicateCard_title: 'Duplica scheda',
|
||||
edit: 'Modifica',
|
||||
editColor_title: 'Modifica colore',
|
||||
|
|
|
@ -201,7 +201,6 @@ export default {
|
|||
deleteTask_title: '작업 삭제',
|
||||
deleteUser: '사용자 삭제',
|
||||
dismissAll: '모두 해제',
|
||||
duplicate: '복제',
|
||||
duplicateCard_title: '카드 복제',
|
||||
edit: '편집',
|
||||
editColor_title: '색상 편집',
|
||||
|
|
|
@ -354,7 +354,6 @@ export default {
|
|||
deleteUser: 'Usuń użytkownika',
|
||||
deleteUser_title: 'Usuń Użytkownika',
|
||||
dismissAll: 'Odrzuć wszystkie',
|
||||
duplicate: 'Duplikuj',
|
||||
duplicateCard_title: 'Duplikuj Kartę',
|
||||
edit: 'Edytuj',
|
||||
editColor_title: 'Edytuj Kolor',
|
||||
|
|
|
@ -360,7 +360,6 @@ export default {
|
|||
deleteUser: 'Удалить пользователя',
|
||||
deleteUser_title: 'Удалить пользователя',
|
||||
dismissAll: 'Отклонить все',
|
||||
duplicate: 'Дублировать',
|
||||
duplicateCard_title: 'Дублировать карточку',
|
||||
edit: 'Изменить',
|
||||
editColor_title: 'Изменить цвет',
|
||||
|
|
|
@ -201,7 +201,6 @@ export default {
|
|||
deleteTask: 'Обриши задатак',
|
||||
deleteTask_title: 'Обриши задатак',
|
||||
deleteUser: 'Обриши корисника',
|
||||
duplicate: 'Клонирај',
|
||||
duplicateCard_title: 'Клонирај картицу',
|
||||
edit: 'Измени',
|
||||
editDescription_title: 'Измени опис',
|
||||
|
|
|
@ -198,7 +198,6 @@ export default {
|
|||
deleteTask: 'Obriši zadatak',
|
||||
deleteTask_title: 'Obriši zadatak',
|
||||
deleteUser: 'Obriši korisnika',
|
||||
duplicate: 'Kloniraj',
|
||||
duplicateCard_title: 'Kloniraj karticu',
|
||||
edit: 'Izmeni',
|
||||
editDescription_title: 'Izmeni opis',
|
||||
|
|
|
@ -356,7 +356,6 @@ export default {
|
|||
deleteUser: 'Видалити користувача',
|
||||
deleteUser_title: 'Видалити Користувача',
|
||||
dismissAll: 'Скасувати всі',
|
||||
duplicate: 'Дублювати',
|
||||
duplicateCard_title: 'Дублювати Картку',
|
||||
edit: 'Редагувати',
|
||||
editColor_title: 'Редагувати колір',
|
||||
|
|
|
@ -368,7 +368,6 @@ export default {
|
|||
deleteUser_title: '删除用户',
|
||||
deleteWebhook: '删除Webhook',
|
||||
dismissAll: '全部忽略',
|
||||
duplicate: '复制卡片',
|
||||
duplicateCard_title: '复制卡片',
|
||||
edit: '编辑',
|
||||
editColor_title: '编辑颜色',
|
||||
|
|
|
@ -430,6 +430,7 @@ export function* transferCurrentCard(boardId, listId, index) {
|
|||
|
||||
export function* duplicateCard(id, data) {
|
||||
const localId = yield call(createLocalId);
|
||||
const { cardId: currentCardId } = yield select(selectors.selectPath);
|
||||
const { boardId, listId } = yield select(selectors.selectCardById, id);
|
||||
const index = yield select(selectors.selectCardIndexById, id);
|
||||
|
||||
|
@ -450,6 +451,10 @@ export function* duplicateCard(id, data) {
|
|||
}),
|
||||
);
|
||||
|
||||
if (id === currentCardId) {
|
||||
yield call(goToBoard, boardId);
|
||||
}
|
||||
|
||||
let card;
|
||||
let cardMemberships;
|
||||
let cardLabels;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue