[GH-526] add copy card link (#795)

* feat: add copy linke to card menu

* style: fix lint issues

* fix: replace add icon with link icon

* tests: update snapshots

* Update webapp/src/components/properties/dateRange/__snapshots__/dateRange.test.tsx.snap

Co-authored-by: Scott Bishel <scott.bishel@mattermost.com>

* add card id to url if not exist

Co-authored-by: Scott Bishel <scott.bishel@mattermost.com>
Co-authored-by: Hossein <hahmadia@users.noreply.github.com>
Co-authored-by: Hossein Ahmadian-Yazdi <hyazdi1997@gmail.com>
This commit is contained in:
defectivepixel 2021-09-24 19:56:03 +03:30 committed by GitHub
parent 0f9486262e
commit 58da537274
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 0 deletions

View file

@ -16,6 +16,8 @@
"CardDetail.new-comment-placeholder": "Add a comment...",
"CardDialog.editing-template": "You're editing a template.",
"CardDialog.nocard": "This card doesn't exist or is inaccessible.",
"CardDialog.copiedLink": "Copied!",
"CardDialog.copyLink": "Copy link",
"ColorOption.selectColor": "Select {color} Color",
"Comment.delete": "Delete",
"CommentsList.send": "Send",
@ -51,11 +53,15 @@
"FilterComponent.delete": "Delete",
"GalleryCard.delete": "Delete",
"GalleryCard.duplicate": "Duplicate",
"GalleryCard.copiedLink": "Copied!",
"GalleryCard.copyLink": "Copy link",
"GroupBy.ungroup": "Ungroup",
"General.BoardCount": "{count, plural, one {# Board} other {# Boards}}",
"KanbanCard.delete": "Delete",
"KanbanCard.duplicate": "Duplicate",
"KanbanCard.untitled": "Untitled",
"KanbanCard.copiedLink": "Copied!",
"KanbanCard.copyLink": "Copy link",
"Mutator.duplicate-board": "duplicate board",
"Mutator.new-board-from-template": "new board from template",
"Mutator.new-card-from-template": "new card from template",

View file

@ -9,6 +9,7 @@ import {BoardView} from '../blocks/boardView'
import {Board} from '../blocks/board'
import {Card} from '../blocks/card'
import DeleteIcon from '../widgets/icons/delete'
import LinkIcon from '../widgets/icons/Link'
import Menu from '../widgets/menu'
import {useAppSelector} from '../store/hooks'
@ -18,6 +19,7 @@ import {getCardComments} from '../store/comments'
import CardDetail from './cardDetail/cardDetail'
import Dialog from './dialog'
import {sendFlashMessage} from './flashMessages'
type Props = {
board: Board
@ -71,6 +73,21 @@ const CardDialog = (props: Props) => {
props.onClose()
}}
/>
<Menu.Text
icon={<LinkIcon/>}
id='copy'
name={intl.formatMessage({id: 'CardDialog.copyLink', defaultMessage: 'Copy link'})}
onClick={() => {
let cardLink = window.location.href
if (!cardLink.includes(props.cardId)) {
cardLink += `/${props.cardId}`
}
Utils.copyTextToClipboard(cardLink)
sendFlashMessage({content: intl.formatMessage({id: 'CardDialog.copiedLink', defaultMessage: 'Copied!'}), severity: 'high'})
}}
/>
{(card && !card.fields.isTemplate) &&
<Menu.Text
id='makeTemplate'

View file

@ -7,11 +7,13 @@ import {Board, IPropertyTemplate} from '../../blocks/board'
import {Card} from '../../blocks/card'
import {ContentBlock} from '../../blocks/contentBlock'
import mutator from '../../mutator'
import {Utils} from '../../utils'
import IconButton from '../../widgets/buttons/iconButton'
import DeleteIcon from '../../widgets/icons/delete'
import DuplicateIcon from '../../widgets/icons/duplicate'
import OptionsIcon from '../../widgets/icons/options'
import LinkIcon from '../../widgets/icons/Link'
import Menu from '../../widgets/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import {useSortable} from '../../hooks/sortable'
@ -19,6 +21,7 @@ import {useSortable} from '../../hooks/sortable'
import ImageElement from '../content/imageElement'
import ContentElement from '../content/contentElement'
import PropertyValueElement from '../propertyValueElement'
import {sendFlashMessage} from '../flashMessages'
import Tooltip from '../../widgets/tooltip'
import {useAppSelector} from '../../store/hooks'
import {getCardContents} from '../../store/contents'
@ -93,6 +96,21 @@ const GalleryCard = React.memo((props: Props) => {
mutator.duplicateCard(card.id)
}}
/>
<Menu.Text
icon={<LinkIcon/>}
id='copy'
name={intl.formatMessage({id: 'GalleryCard.copyLink', defaultMessage: 'Copy link'})}
onClick={() => {
let cardLink = window.location.href
if (!cardLink.includes(card.id)) {
cardLink += `/${card.id}`
}
Utils.copyTextToClipboard(cardLink)
sendFlashMessage({content: intl.formatMessage({id: 'GalleryCard.copiedLink', defaultMessage: 'Copied!'}), severity: 'high'})
}}
/>
</Menu>
</MenuWrapper>
}

View file

@ -10,9 +10,12 @@ import IconButton from '../../widgets/buttons/iconButton'
import DeleteIcon from '../../widgets/icons/delete'
import DuplicateIcon from '../../widgets/icons/duplicate'
import OptionsIcon from '../../widgets/icons/options'
import LinkIcon from '../../widgets/icons/Link'
import Menu from '../../widgets/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import {useSortable} from '../../hooks/sortable'
import {Utils} from '../../utils'
import {sendFlashMessage} from '../flashMessages'
import {useAppSelector} from '../../store/hooks'
import {getCardContents} from '../../store/contents'
import {getCardComments} from '../../store/comments'
@ -85,6 +88,21 @@ const KanbanCard = React.memo((props: Props) => {
)
}}
/>
<Menu.Text
icon={<LinkIcon/>}
id='copy'
name={intl.formatMessage({id: 'KanbanCard.copyLink', defaultMessage: 'Copy link'})}
onClick={() => {
let cardLink = window.location.href
if (!cardLink.includes(card.id)) {
cardLink += `/${card.id}`
}
Utils.copyTextToClipboard(cardLink)
sendFlashMessage({content: intl.formatMessage({id: 'KanbanCard.copiedLink', defaultMessage: 'Copied!'}), severity: 'high'})
}}
/>
</Menu>
</MenuWrapper>
}

View file

@ -5,6 +5,8 @@ import React from 'react'
import CompassIcon from './compassIcon'
import './link.scss'
export default function LinkIcon(): JSX.Element {
return (
<CompassIcon

View file

@ -0,0 +1,10 @@
.LinkIcon {
color: rgba(var(--body-color), 0.5);
font-size: 18px;
width: 16px;
&::before {
margin: 0 !important;
}
}