Skip to content

Commit

Permalink
Add copy button to export overlays
Browse files Browse the repository at this point in the history
  • Loading branch information
ischolten committed Mar 22, 2019
1 parent 8196a00 commit c19cfdc
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
1. [12706](https://github.com/influxdata/influxdb/pull/12706): Add ability to add variable to script from the side menu.
1. [12791](https://github.com/influxdata/influxdb/pull/12791): Use time range for metaqueries in Data Explorer and Cell Editor Overlay
1. [12827](https://github.com/influxdata/influxdb/pull/12827): Fix screen tearing bug in Raw Data View
1. [12843](https://github.com/influxdata/influxdb/pull/12843): Add copy to clipboard button to export overlays

### Bug Fixes

Expand Down
44 changes: 3 additions & 41 deletions ui/src/shared/components/CodeSnippet.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
// Libraries
import React, {PureComponent, MouseEvent} from 'react'
import React, {PureComponent} from 'react'
import _ from 'lodash'
import CopyToClipboard from 'react-copy-to-clipboard'

// Decorator
import {ErrorHandling} from 'src/shared/decorators/errors'

// Components
import {Button, ComponentSize, ComponentColor} from '@influxdata/clockface'
import FancyScrollbar from 'src/shared/components/fancy_scrollbar/FancyScrollbar'

// Actions
import {NotificationAction} from 'src/types'
import {
copyToClipboardSuccess,
copyToClipboardFailed,
} from 'src/shared/copy/notifications'
import CopyButton from 'src/shared/components/CopyButton'

// Styles
import 'src/shared/components/CodeSnippet.scss'

export interface PassedProps {
copyText: string
notify: NotificationAction
}

interface DefaultProps {
Expand Down Expand Up @@ -54,41 +45,12 @@ class CodeSnippet extends PureComponent<Props> {
</div>
</FancyScrollbar>
<div className="code-snippet--footer">
<CopyToClipboard text={copyText} onCopy={this.handleCopyAttempt}>
<Button
size={ComponentSize.ExtraSmall}
color={ComponentColor.Secondary}
titleText="Copy to Clipboard"
text="Copy to Clipboard"
onClick={this.handleClickCopy}
/>
</CopyToClipboard>
<CopyButton textToCopy={copyText} contentName={'Script'} />
<label className="code-snippet--label">{label}</label>
</div>
</div>
)
}

private handleClickCopy = (e: MouseEvent<HTMLButtonElement>) => {
e.stopPropagation()
e.preventDefault()
}

private handleCopyAttempt = (
copiedText: string,
isSuccessful: boolean
): void => {
const {notify} = this.props
const text = copiedText.slice(0, 30).trimRight()
const truncatedText = `${text}...`
const title = 'Script '

if (isSuccessful) {
notify(copyToClipboardSuccess(truncatedText, title))
} else {
notify(copyToClipboardFailed(truncatedText, title))
}
}
}

export default CodeSnippet
84 changes: 84 additions & 0 deletions ui/src/shared/components/CopyButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Libraries
import React, {PureComponent, MouseEvent} from 'react'
import CopyToClipboard from 'react-copy-to-clipboard'
import {connect} from 'react-redux'

// Components
import {Button, ComponentColor, ComponentSize} from '@influxdata/clockface'

// Constants
import {
copyToClipboardSuccess,
copyToClipboardFailed,
} from 'src/shared/copy/notifications'

// Actions
import {notify as notifyAction} from 'src/shared/actions/notifications'

interface OwnProps {
textToCopy: string
contentName: string // if copying a script, its "script"
size?: ComponentSize
color?: ComponentColor
}

interface DefaultProps {
size: ComponentSize
color: ComponentColor
}

interface DispatchProps {
notify: typeof notifyAction
}

type Props = OwnProps & DispatchProps

class CopyButton extends PureComponent<Props> {
public static defaultProps: DefaultProps = {
size: ComponentSize.ExtraSmall,
color: ComponentColor.Secondary,
}
public render() {
const {textToCopy, color, size} = this.props

return (
<CopyToClipboard text={textToCopy} onCopy={this.handleCopyAttempt}>
<Button
size={size}
color={color}
titleText="Copy to Clipboard"
text="Copy to Clipboard"
onClick={this.handleClickCopy}
/>
</CopyToClipboard>
)
}
private handleClickCopy = (e: MouseEvent<HTMLButtonElement>) => {
e.stopPropagation()
e.preventDefault()
}

private handleCopyAttempt = (
copiedText: string,
isSuccessful: boolean
): void => {
const {contentName, notify} = this.props
const text = copiedText.slice(0, 30).trimRight()
const truncatedText = `${text}...`

if (isSuccessful) {
notify(copyToClipboardSuccess(truncatedText, contentName))
} else {
notify(copyToClipboardFailed(truncatedText, contentName))
}
}
}

const mdtp: DispatchProps = {
notify: notifyAction,
}

export default connect<{}, DispatchProps, OwnProps>(
null,
mdtp
)(CopyButton)
21 changes: 19 additions & 2 deletions ui/src/shared/components/ExportOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import {Form} from 'src/clockface'
import {
Button,
ComponentColor,
ComponentSize,
SpinnerContainer,
TechnoSpinner,
} from '@influxdata/clockface'
import {Controlled as ReactCodeMirror} from 'react-codemirror2'
import CopyButton from 'src/shared/components/CopyButton'

// Actions
import {notify as notifyAction} from 'src/shared/actions/notifications'
Expand Down Expand Up @@ -76,6 +78,7 @@ class ExportOverlay extends PureComponent<Props> {
<Overlay.Footer>
{this.downloadButton}
{this.toTemplateButton}
{this.copyButton}
</Overlay.Footer>
</Form>
</Overlay.Container>
Expand All @@ -86,7 +89,6 @@ class ExportOverlay extends PureComponent<Props> {
private doNothing = () => {}

private get overlayBody(): JSX.Element {
const {resource} = this.props
const options = {
tabIndex: 1,
mode: 'json',
Expand All @@ -101,7 +103,7 @@ class ExportOverlay extends PureComponent<Props> {
<ReactCodeMirror
autoFocus={false}
autoCursor={true}
value={JSON.stringify(resource, null, 1)}
value={this.resourceText}
options={options}
onBeforeChange={this.doNothing}
onTouchStart={this.doNothing}
Expand All @@ -110,6 +112,21 @@ class ExportOverlay extends PureComponent<Props> {
)
}

private get resourceText(): string {
return JSON.stringify(this.props.resource, null, 1)
}

private get copyButton(): JSX.Element {
return (
<CopyButton
textToCopy={this.resourceText}
contentName={this.props.resourceName}
size={ComponentSize.Small}
color={ComponentColor.Secondary}
/>
)
}

private get downloadButton(): JSX.Element {
return (
<Button
Expand Down
2 changes: 1 addition & 1 deletion ui/src/shared/copy/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ export const copyToClipboardSuccess = (
): Notification => ({
...defaultSuccessNotification,
icon: 'dash-h',
message: `${title}'${text}' has been copied to clipboard.`,
message: `${title} '${text}' has been copied to clipboard.`,
})

export const copyToClipboardFailed = (
Expand Down

0 comments on commit c19cfdc

Please sign in to comment.