From fba156b27193baad31a577106e3b3d458bc63ed6 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Fri, 6 Mar 2020 21:22:07 +0100 Subject: [PATCH] Moved copy-to-clipboard control next to short URL --- src/index.scss | 4 -- src/short-urls/ShortUrlsList.js | 2 +- src/short-urls/helpers/ShortUrlsRow.js | 37 +++++++++++-------- src/short-urls/helpers/ShortUrlsRow.scss | 11 ++++-- src/short-urls/helpers/ShortUrlsRowMenu.js | 33 +++++------------ src/utils/mixins/vertical-align.scss | 4 +- test/short-urls/helpers/ShortUrlsRow.test.js | 9 +++-- .../helpers/ShortUrlsRowMenu.test.js | 4 +- 8 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/index.scss b/src/index.scss index b2a386ee..480dd907 100644 --- a/src/index.scss +++ b/src/index.scss @@ -10,10 +10,6 @@ body, outline: none !important; } -.nowrap { - white-space: nowrap; -} - .bg-main { background-color: $mainColor !important; } diff --git a/src/short-urls/ShortUrlsList.js b/src/short-urls/ShortUrlsList.js index ffc9cd21..94fb0b10 100644 --- a/src/short-urls/ShortUrlsList.js +++ b/src/short-urls/ShortUrlsList.js @@ -161,7 +161,7 @@ const ShortUrlsList = (ShortUrlsRow) => class ShortUrlsList extends React.Compon className="short-urls-list__header-cell short-urls-list__header-cell--with-action" onClick={this.orderByColumn('visits')} > - {this.renderOrderIcon('visits')} Visits + {this.renderOrderIcon('visits')} Visits   diff --git a/src/short-urls/helpers/ShortUrlsRow.js b/src/short-urls/helpers/ShortUrlsRow.js index a0cbf4a8..0a2b66b6 100644 --- a/src/short-urls/helpers/ShortUrlsRow.js +++ b/src/short-urls/helpers/ShortUrlsRow.js @@ -3,6 +3,9 @@ import React from 'react'; import Moment from 'react-moment'; import PropTypes from 'prop-types'; import { ExternalLink } from 'react-external-link'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faCopy as copyIcon } from '@fortawesome/free-regular-svg-icons'; +import { CopyToClipboard } from 'react-copy-to-clipboard'; import { shortUrlsListParamsType } from '../reducers/shortUrlsListParams'; import { serverType } from '../../servers/prop-types'; import { shortUrlType } from '../reducers/shortUrlsList'; @@ -26,7 +29,7 @@ const ShortUrlsRow = ( renderTags(tags) { if (isEmpty(tags)) { - return No tags; + return No tags; } const { refreshList, shortUrlsListParams } = this.props; @@ -47,11 +50,25 @@ const ShortUrlsRow = ( return ( - + {shortUrl.dateCreated} - + + + stateFlagTimeout(this.setState.bind(this), 'copiedToClipboard')} + > + + + + @@ -64,18 +81,8 @@ const ShortUrlsRow = ( selectedServer={selectedServer} /> - - - stateFlagTimeout(this.setState.bind(this), 'copiedToClipboard')} - /> + + ); diff --git a/src/short-urls/helpers/ShortUrlsRow.scss b/src/short-urls/helpers/ShortUrlsRow.scss index da6e8f86..7a888cf3 100644 --- a/src/short-urls/helpers/ShortUrlsRow.scss +++ b/src/short-urls/helpers/ShortUrlsRow.scss @@ -43,11 +43,16 @@ position: relative; } +.short-urls-row__copy-btn { + cursor: pointer; + font-size: 1.2rem; +} + .short-urls-row__copy-hint { - @include vertical-align(); - right: 100%; + @include vertical-align(translateX(10px)); + box-shadow: 0 3px 15px rgba(0, 0, 0, .25); @media (max-width: $smMax) { - right: calc(100% + 10px); + @include vertical-align(translateX(calc(-100% - 20px))); } } diff --git a/src/short-urls/helpers/ShortUrlsRowMenu.js b/src/short-urls/helpers/ShortUrlsRowMenu.js index 1915883a..0e8a149d 100644 --- a/src/short-urls/helpers/ShortUrlsRowMenu.js +++ b/src/short-urls/helpers/ShortUrlsRowMenu.js @@ -1,4 +1,4 @@ -import { faCopy as copyIcon, faImage as pictureIcon } from '@fortawesome/free-regular-svg-icons'; +import { faImage as pictureIcon } from '@fortawesome/free-regular-svg-icons'; import { faTags as tagsIcon, faChartPie as pieChartIcon, @@ -9,9 +9,7 @@ import { } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import React from 'react'; -import { CopyToClipboard } from 'react-copy-to-clipboard'; import { ButtonDropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap'; -import PropTypes from 'prop-types'; import { serverType } from '../../servers/prop-types'; import { shortUrlType } from '../reducers/shortUrlsList'; import PreviewModal from './PreviewModal'; @@ -26,7 +24,6 @@ const ShortUrlsRowMenu = ( ForServerVersion ) => class ShortUrlsRowMenu extends React.Component { static propTypes = { - onCopyToClipboard: PropTypes.func, selectedServer: serverType, shortUrl: shortUrlType, }; @@ -42,7 +39,7 @@ const ShortUrlsRowMenu = ( toggle = () => this.setState(({ isOpen }) => ({ isOpen: !isOpen })); render() { - const { onCopyToClipboard, shortUrl, selectedServer } = this.props; + const { shortUrl, selectedServer } = this.props; const completeShortUrl = shortUrl && shortUrl.shortUrl ? shortUrl.shortUrl : ''; const toggleModal = (prop) => () => this.setState((prevState) => ({ [prop]: !prevState[prop] })); const toggleQrCode = toggleModal('isQrModalOpen'); @@ -73,12 +70,10 @@ const ShortUrlsRowMenu = ( - - Delete short URL + + QR code - - - + @@ -87,20 +82,12 @@ const ShortUrlsRowMenu = ( - - QR code + + + + Delete short URL - - - - - - - - - Copy to clipboard - - + ); diff --git a/src/utils/mixins/vertical-align.scss b/src/utils/mixins/vertical-align.scss index d9fd0a0b..5af5038c 100644 --- a/src/utils/mixins/vertical-align.scss +++ b/src/utils/mixins/vertical-align.scss @@ -1,5 +1,5 @@ -@mixin vertical-align { +@mixin vertical-align($extraTransforms: '') { position: absolute; top: 50%; - transform: translateY(-50%); + transform: translateY(-50%) $extraTransforms; } diff --git a/test/short-urls/helpers/ShortUrlsRow.test.js b/test/short-urls/helpers/ShortUrlsRow.test.js index cb6d9a77..dd12a39f 100644 --- a/test/short-urls/helpers/ShortUrlsRow.test.js +++ b/test/short-urls/helpers/ShortUrlsRow.test.js @@ -4,6 +4,7 @@ import moment from 'moment'; import Moment from 'react-moment'; import { assoc, toString } from 'ramda'; import { ExternalLink } from 'react-external-link'; +import { CopyToClipboard } from 'react-copy-to-clipboard'; import createShortUrlsRow from '../../../src/short-urls/helpers/ShortUrlsRow'; import Tag from '../../../src/tags/helpers/Tag'; @@ -87,17 +88,17 @@ describe('', () => { }); it('updates state when copied to clipboard', () => { - const col = wrapper.find('td').at(5); - const menu = col.find(ShortUrlsRowMenu); + const col = wrapper.find('td').at(1); + const menu = col.find(CopyToClipboard); expect(menu).toHaveLength(1); expect(stateFlagTimeout).not.toHaveBeenCalled(); - menu.simulate('copyToClipboard'); + menu.simulate('copy'); expect(stateFlagTimeout).toHaveBeenCalledTimes(1); }); it('shows copy hint when state prop is true', () => { - const isHidden = () => wrapper.find('td').at(5).find('.short-urls-row__copy-hint').prop('hidden'); + const isHidden = () => wrapper.find('td').at(1).find('.short-urls-row__copy-hint').prop('hidden'); expect(isHidden()).toEqual(true); wrapper.setState({ copiedToClipboard: true }); diff --git a/test/short-urls/helpers/ShortUrlsRowMenu.test.js b/test/short-urls/helpers/ShortUrlsRowMenu.test.js index cfcee90d..8ffd0d38 100644 --- a/test/short-urls/helpers/ShortUrlsRowMenu.test.js +++ b/test/short-urls/helpers/ShortUrlsRowMenu.test.js @@ -49,8 +49,8 @@ describe('', () => { const wrapper = createWrapper(); const items = wrapper.find(DropdownItem); - expect(items).toHaveLength(9); - expect(items.find('[divider]')).toHaveLength(2); + expect(items).toHaveLength(7); + expect(items.find('[divider]')).toHaveLength(1); }); describe('toggles state when toggling modal windows', () => {