1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-08-09 07:25:24 +02:00

feat: add copy link action to card modal

This commit is contained in:
HannesOberreiter 2024-06-20 15:53:39 +02:00
parent ba178d66fa
commit 0e79684f05
4 changed files with 38 additions and 3 deletions

View file

@ -1,4 +1,4 @@
import React, { useCallback, useRef } from 'react'; import React, { useCallback, useRef, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -83,6 +83,7 @@ const CardModal = React.memo(
const [t] = useTranslation(); const [t] = useTranslation();
const isGalleryOpened = useRef(false); const isGalleryOpened = useRef(false);
const [isLinkCopied, setIsLinkCopied] = useState(false);
const handleToggleStopwatchClick = useCallback(() => { const handleToggleStopwatchClick = useCallback(() => {
onUpdate({ onUpdate({
@ -162,6 +163,14 @@ const CardModal = React.memo(
onClose(); onClose();
}, [onClose]); }, [onClose]);
const handleLinkCopyClick = useCallback(() => {
navigator.clipboard.writeText(window.location.href);
setIsLinkCopied(true);
setTimeout(() => {
setIsLinkCopied(false);
}, 5000);
}, []);
const AttachmentAddPopup = usePopup(AttachmentAddStep); const AttachmentAddPopup = usePopup(AttachmentAddStep);
const BoardMembershipsPopup = usePopup(BoardMembershipsStep); const BoardMembershipsPopup = usePopup(BoardMembershipsStep);
const LabelsPopup = usePopup(LabelsStep); const LabelsPopup = usePopup(LabelsStep);
@ -517,6 +526,10 @@ const CardModal = React.memo(
{t('action.delete')} {t('action.delete')}
</Button> </Button>
</DeletePopup> </DeletePopup>
<Button fluid className={styles.actionButton} onClick={handleLinkCopyClick}>
<Icon name={isLinkCopied ? 'linkify' : 'unlink'} className={styles.actionIcon} />
{isLinkCopied ? t('action.linkIsCopied') : t('action.linkCopy')}
</Button>
</div> </div>
</Grid.Column> </Grid.Column>
)} )}

View file

@ -201,6 +201,8 @@ export default {
hideDetails: 'Details ausblenden', hideDetails: 'Details ausblenden',
leaveBoard: 'Board verlassen', leaveBoard: 'Board verlassen',
leaveProject: 'Projekt verlassen', leaveProject: 'Projekt verlassen',
linkCopy: 'Link kopieren',
linkIsCopied: 'Link kopiert',
logOut_title: 'Ausloggen', logOut_title: 'Ausloggen',
makeCover_title: 'Als Vorschau festlegen', makeCover_title: 'Als Vorschau festlegen',
move: 'Verschieben', move: 'Verschieben',

View file

@ -220,6 +220,8 @@ export default {
import: 'Import', import: 'Import',
leaveBoard: 'Leave board', leaveBoard: 'Leave board',
leaveProject: 'Leave project', leaveProject: 'Leave project',
linkCopy: 'Copy link',
linkIsCopied: 'Link is copied',
logOut_title: 'Log Out', logOut_title: 'Log Out',
makeCover_title: 'Make Cover', makeCover_title: 'Make Cover',
move: 'Move', move: 'Move',

View file

@ -82,8 +82,12 @@ module.exports = {
const importComments = async (plankaCard, trelloCard) => { const importComments = async (plankaCard, trelloCard) => {
const trelloComments = getTrelloCommentsOfCard(trelloCard.id); const trelloComments = getTrelloCommentsOfCard(trelloCard.id);
trelloComments.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()); trelloComments.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
if (trelloCard.id === '64e5c9be1f2b91b351be443b') {
console.log(trelloComments);
}
console.log('trelloComments', trelloComments.length);
return Promise.all( const result = Promise.allSettled(
trelloComments.map(async (trelloComment) => { trelloComments.map(async (trelloComment) => {
return Action.create({ return Action.create({
cardId: plankaCard.id, cardId: plankaCard.id,
@ -94,9 +98,23 @@ module.exports = {
`${trelloComment.data.text}\n\n---\n*Note: imported comment, originally posted by ` + `${trelloComment.data.text}\n\n---\n*Note: imported comment, originally posted by ` +
`\n${trelloComment.memberCreator.fullName} (${trelloComment.memberCreator.username}) on ${trelloComment.date}*`, `\n${trelloComment.memberCreator.fullName} (${trelloComment.memberCreator.username}) on ${trelloComment.date}*`,
}, },
}).fetch(); })
.fetch()
.catch((err) => {
console.log('err', err);
});
}), }),
); );
const res = await result;
if (res.length > 0) {
for (let i = 0; i < res.length; i++) {
if (res[i].status === 'rejected') {
console.log('res[i].reason', res[i].reason);
}
}
}
return result;
}; };
const importCards = async (plankaList, trelloList) => { const importCards = async (plankaList, trelloList) => {