From: Grégoire Aubert Date: Wed, 10 Jan 2018 16:28:51 +0000 (+0100) Subject: Create a Clipboard button X-Git-Tag: 7.5~1789 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b3a593c103415e903db6974cc293c3dce462e20f;p=sonarqube.git Create a Clipboard button --- diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Command.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Command.js index efa4ee1c2e6..23d728a407e 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Command.js +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Command.js @@ -19,9 +19,8 @@ */ // @flow import React from 'react'; -import Clipboard from 'clipboard'; import classNames from 'classnames'; -import Tooltip from '../../../../components/controls/Tooltip'; +import ClipboardButton from '../../../../components/controls/ClipboardButton'; import { translate } from '../../../../helpers/l10n'; /*:: @@ -31,73 +30,21 @@ type Props = { }; */ -/*:: -type State = { - tooltipShown: boolean -}; -*/ - const s = ' \\' + '\n '; export default class Command extends React.PureComponent { - /*:: clipboard: Object; */ - /*:: copyButton: HTMLButtonElement; */ - /*:: mounted: boolean; */ /*:: props: Props; */ - state /*: State */ = { tooltipShown: false }; - - componentDidMount() { - this.mounted = true; - this.clipboard = new Clipboard(this.copyButton); - this.clipboard.on('success', this.showTooltip); - } - - componentDidUpdate() { - this.clipboard.destroy(); - this.clipboard = new Clipboard(this.copyButton); - this.clipboard.on('success', this.showTooltip); - } - - componentWillUnmount() { - this.mounted = false; - this.clipboard.destroy(); - } - - showTooltip = () => { - if (this.mounted) { - this.setState({ tooltipShown: true }); - setTimeout(this.hideTooltip, 1000); - } - }; - - hideTooltip = () => { - if (this.mounted) { - this.setState({ tooltipShown: false }); - } - }; render() { const { command, isWindows } = this.props; const commandArray = Array.isArray(command) ? command.filter(line => line != null) : [command]; const finalCommand = isWindows ? commandArray.join(' ') : commandArray.join(s); - const button = ( - - ); - return (
{finalCommand}
- {this.state.tooltipShown ? ( - - {button} - - ) : ( - button - )} +
); } diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Command-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Command-test.js.snap index 63e31484c8d..2bd0aafd5b8 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Command-test.js.snap +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Command-test.js.snap @@ -12,12 +12,19 @@ bar" foo bar - + + `; diff --git a/server/sonar-web/src/main/js/apps/users/components/TokensFormNewToken.tsx b/server/sonar-web/src/main/js/apps/users/components/TokensFormNewToken.tsx index e3bb9df6b32..f7b744e9c1f 100644 --- a/server/sonar-web/src/main/js/apps/users/components/TokensFormNewToken.tsx +++ b/server/sonar-web/src/main/js/apps/users/components/TokensFormNewToken.tsx @@ -18,84 +18,21 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import * as Clipboard from 'clipboard'; -import Tooltip from '../../../components/controls/Tooltip'; -import { translate, translateWithParameters } from '../../../helpers/l10n'; +import ClipboardButton from '../../../components/controls/ClipboardButton'; +import { translateWithParameters } from '../../../helpers/l10n'; interface Props { token: { name: string; token: string }; } -interface State { - tooltipShown: boolean; -} - -export default class TokensFormNewToken extends React.PureComponent { - clipboard: Clipboard; - copyButton: HTMLButtonElement | null; - mounted: boolean; - state: State = { tooltipShown: false }; - - componentDidMount() { - this.mounted = true; - if (this.copyButton) { - this.clipboard = new Clipboard(this.copyButton); - this.clipboard.on('success', this.showTooltip); - } - } - - componentDidUpdate() { - this.clipboard.destroy(); - if (this.copyButton) { - this.clipboard = new Clipboard(this.copyButton); - this.clipboard.on('success', this.showTooltip); - } - } - - componentWillUnmount() { - this.mounted = false; - this.clipboard.destroy(); - } - - showTooltip = () => { - if (this.mounted) { - this.setState({ tooltipShown: true }); - setTimeout(() => { - if (this.mounted) { - this.setState({ tooltipShown: false }); - } - }, 1000); - } - }; - - render() { - const { name, token } = this.props.token; - const button = ( - - ); - return ( -
-

- {translateWithParameters('users.tokens.new_token_created', name)} -

- {this.state.tooltipShown ? ( - - {button} - - ) : ( - button - )} - {token} -
- ); - } +export default function TokensFormNewToken({ token }: Props) { + return ( +
+

+ {translateWithParameters('users.tokens.new_token_created', token.name)} +

+ + {token.token} +
+ ); } diff --git a/server/sonar-web/src/main/js/components/controls/ClipboardButton.tsx b/server/sonar-web/src/main/js/components/controls/ClipboardButton.tsx new file mode 100644 index 00000000000..dc9b146d13e --- /dev/null +++ b/server/sonar-web/src/main/js/components/controls/ClipboardButton.tsx @@ -0,0 +1,98 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import * as classNames from 'classnames'; +import * as Clipboard from 'clipboard'; +import Tooltip from './Tooltip'; +import { translate } from '../../helpers/l10n'; + +interface Props { + className?: string; + copyValue: string; + tooltipPlacement?: string; +} + +interface State { + tooltipShown: boolean; +} + +export default class ClipboardButton extends React.PureComponent { + clipboard: Clipboard; + copyButton: HTMLButtonElement | null; + mounted: boolean; + state: State = { tooltipShown: false }; + + componentDidMount() { + this.mounted = true; + if (this.copyButton) { + this.clipboard = new Clipboard(this.copyButton); + this.clipboard.on('success', this.showTooltip); + } + } + + componentDidUpdate() { + if (this.clipboard) { + this.clipboard.destroy(); + } + if (this.copyButton) { + this.clipboard = new Clipboard(this.copyButton); + this.clipboard.on('success', this.showTooltip); + } + } + + componentWillUnmount() { + this.mounted = false; + this.clipboard.destroy(); + } + + showTooltip = () => { + if (this.mounted) { + this.setState({ tooltipShown: true }); + setTimeout(() => { + if (this.mounted) { + this.setState({ tooltipShown: false }); + } + }, 1000); + } + }; + + render() { + const button = ( + + ); + if (this.state.tooltipShown) { + return ( + + {button} + + ); + } + return button; + } +} diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/ClipboardButton-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/ClipboardButton-test.tsx new file mode 100644 index 00000000000..a33520ea19e --- /dev/null +++ b/server/sonar-web/src/main/js/components/controls/__tests__/ClipboardButton-test.tsx @@ -0,0 +1,35 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import ClipboardButton from '../ClipboardButton'; + +jest.useFakeTimers(); + +it('should display correctly', () => { + const wrapper = shallow(); + expect(wrapper).toMatchSnapshot(); + (wrapper.instance() as ClipboardButton).showTooltip(); + wrapper.update(); + expect(wrapper).toMatchSnapshot(); + jest.runAllTimers(); + wrapper.update(); + expect(wrapper.find('Tooltip')).toHaveLength(0); +}); diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ClipboardButton-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ClipboardButton-test.tsx.snap new file mode 100644 index 00000000000..61870f73365 --- /dev/null +++ b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ClipboardButton-test.tsx.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should display correctly 1`] = ` + +`; + +exports[`should display correctly 2`] = ` + + + +`; diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 89c5ededa57..ce5c514e171 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -198,9 +198,10 @@ are_you_sure=Are you sure? assigned_to=Assigned to bulk_change=Bulk Change bulleted_point=Bulleted point -coding_rules=Rules clear=Clear clear_all_filters=Clear All Filters +coding_rules=Rules +copied_action=Copied! created_by=Created by default_error_message=The request cannot be processed. Try again later. default_severity=Default severity