diff --git a/worklenz-frontend/public/locales/alb/task-list-table.json b/worklenz-frontend/public/locales/alb/task-list-table.json index c009e734..bf2542cf 100644 --- a/worklenz-frontend/public/locales/alb/task-list-table.json +++ b/worklenz-frontend/public/locales/alb/task-list-table.json @@ -57,6 +57,9 @@ "contextMenu": { "assignToMe": "Cakto mua", + "copyLink": "Kopjo lidhjen e detyrës", + "linkCopied": "Lidhja u kopjua në clipboard", + "linkCopyFailed": "Dështoi kopjimi i lidhjes", "moveTo": "Zhvendos në", "unarchive": "Ç'arkivizo", "archive": "Arkivizo", diff --git a/worklenz-frontend/public/locales/de/task-list-table.json b/worklenz-frontend/public/locales/de/task-list-table.json index 23439a1b..21353b54 100644 --- a/worklenz-frontend/public/locales/de/task-list-table.json +++ b/worklenz-frontend/public/locales/de/task-list-table.json @@ -57,6 +57,9 @@ "contextMenu": { "assignToMe": "Mir zuweisen", + "copyLink": "Link zur Aufgabe kopieren", + "linkCopied": "Link in die Zwischenablage kopiert", + "linkCopyFailed": "Fehler beim Kopieren des Links", "moveTo": "Verschieben nach", "unarchive": "Dearchivieren", "archive": "Archivieren", diff --git a/worklenz-frontend/public/locales/en/task-list-table.json b/worklenz-frontend/public/locales/en/task-list-table.json index abd97ca5..6d05d6b9 100644 --- a/worklenz-frontend/public/locales/en/task-list-table.json +++ b/worklenz-frontend/public/locales/en/task-list-table.json @@ -57,6 +57,9 @@ "contextMenu": { "assignToMe": "Assign to me", + "copyLink": "Copy link to task", + "linkCopied": "Link copied to clipboard", + "linkCopyFailed": "Failed to copy link", "moveTo": "Move to", "unarchive": "Unarchive", "archive": "Archive", diff --git a/worklenz-frontend/public/locales/es/task-list-table.json b/worklenz-frontend/public/locales/es/task-list-table.json index 779c76ed..0ff70a2f 100644 --- a/worklenz-frontend/public/locales/es/task-list-table.json +++ b/worklenz-frontend/public/locales/es/task-list-table.json @@ -57,6 +57,9 @@ "contextMenu": { "assignToMe": "Asignar a mí", + "copyLink": "Copiar enlace a la tarea", + "linkCopied": "Enlace copiado al portapapeles", + "linkCopyFailed": "Error al copiar el enlace", "moveTo": "Mover a", "unarchive": "Desarchivar", "archive": "Archivar", diff --git a/worklenz-frontend/public/locales/pt/task-list-table.json b/worklenz-frontend/public/locales/pt/task-list-table.json index 54fd2a33..6726b32c 100644 --- a/worklenz-frontend/public/locales/pt/task-list-table.json +++ b/worklenz-frontend/public/locales/pt/task-list-table.json @@ -57,6 +57,9 @@ "contextMenu": { "assignToMe": "Atribuir a mim", + "copyLink": "Copiar link da tarefa", + "linkCopied": "Link copiado para a área de transferência", + "linkCopyFailed": "Falha ao copiar o link", "moveTo": "Mover para", "unarchive": "Desarquivar", "archive": "Arquivar", diff --git a/worklenz-frontend/public/locales/zh/task-list-table.json b/worklenz-frontend/public/locales/zh/task-list-table.json index 63718830..8d3dc9bb 100644 --- a/worklenz-frontend/public/locales/zh/task-list-table.json +++ b/worklenz-frontend/public/locales/zh/task-list-table.json @@ -50,6 +50,9 @@ "pendingInvitation": "待处理邀请", "contextMenu": { "assignToMe": "分配给我", + "copyLink": "复制任务链接", + "linkCopied": "链接已复制到剪贴板", + "linkCopyFailed": "复制链接失败", "moveTo": "移动到", "unarchive": "取消归档", "archive": "归档", diff --git a/worklenz-frontend/src/components/task-list-v2/components/TaskContextMenu.tsx b/worklenz-frontend/src/components/task-list-v2/components/TaskContextMenu.tsx index 3509f6c9..90019757 100644 --- a/worklenz-frontend/src/components/task-list-v2/components/TaskContextMenu.tsx +++ b/worklenz-frontend/src/components/task-list-v2/components/TaskContextMenu.tsx @@ -32,6 +32,8 @@ import { RetweetOutlined, UserAddOutlined, LoadingOutlined, + CopyOutlined, + message, } from '@/shared/antd-imports'; interface TaskContextMenuProps { @@ -325,6 +327,21 @@ const TaskContextMenu: React.FC = ({ } }, [task?.id, projectId, dispatch, onClose]); + const handleCopyLink = useCallback(async () => { + if (!projectId || !task.id) return; + + try { + const taskLink = `${window.location.origin}/worklenz/projects/${projectId}?tab=tasks-list&pinned_tab=tasks-list&task=${task.id}`; + await navigator.clipboard.writeText(taskLink); + message.success(t('contextMenu.linkCopied')); + } catch (error) { + logger.error('Error copying link:', error); + message.error(t('contextMenu.linkCopyFailed')); + } finally { + onClose(); + } + }, [projectId, task.id, onClose, t]); + const menuItems = useMemo(() => { const items = [ { @@ -344,6 +361,18 @@ const TaskContextMenu: React.FC = ({ ), }, + { + key: 'copyLink', + label: ( + + ), + }, ]; // Add Move To submenu if there are options @@ -500,6 +529,7 @@ const TaskContextMenu: React.FC = ({ handleArchive, handleDelete, handleConvertToTask, + handleCopyLink, getMoveToOptions, dispatch, t, diff --git a/worklenz-frontend/src/shared/antd-imports.ts b/worklenz-frontend/src/shared/antd-imports.ts index db7bdcb0..e9f312d9 100644 --- a/worklenz-frontend/src/shared/antd-imports.ts +++ b/worklenz-frontend/src/shared/antd-imports.ts @@ -182,7 +182,8 @@ export { InfoCircleOutlined, WarningTwoTone, ShareAltOutlined, - CloudDownloadOutlined + CloudDownloadOutlined, + CopyOutlined } from '@ant-design/icons'; // Re-export all components with React