Skip to content

Commit a466d3c

Browse files
feat(dashboards): add copy query item to cell context menu (#5875)
1 parent 398fc17 commit a466d3c

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

src/shared/components/CopyToClipboard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Libraries
22
import React, {FC, ChangeEvent} from 'react'
33

4-
const copy = async (text: string): Promise<boolean> => {
4+
export const copy = async (text: string): Promise<boolean> => {
55
let result: boolean
66
try {
77
if (navigator.clipboard) {

src/shared/components/cells/CellContext.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import classnames from 'classnames'
77

88
// Utils
99
import {event} from 'src/cloud/utils/reporting'
10+
import {copy} from 'src/shared/components/CopyToClipboard'
11+
import {
12+
copyQuerySuccess,
13+
copyQueryFailure,
14+
} from 'src/shared/copy/notifications/categories/dashboard'
1015

1116
// Components
1217
import {
@@ -22,6 +27,7 @@ import CellContextDangerItem from 'src/shared/components/cells/CellContextDanger
2227
// Actions
2328
import {deleteCellAndView, createCellWithView} from 'src/cells/actions/thunks'
2429
import {showOverlay, dismissOverlay} from 'src/overlays/actions/overlays'
30+
import {notify} from 'src/shared/actions/notifications'
2531

2632
// Types
2733
import {Cell, View} from 'src/types'
@@ -76,6 +82,20 @@ const CellContext: FC<Props> = ({
7682
event('editCell button Click')
7783
}
7884

85+
const handleCopyQuery = async () => {
86+
let result = false
87+
// this 'in' check satisfies TypeScript saying `property queries does not exist in ViewProperties` (which is a lie)
88+
if ('queries' in view.properties) {
89+
result = await copy(view.properties.queries?.[0]?.text)
90+
}
91+
92+
if (!result) {
93+
dispatch(notify(copyQueryFailure(cell.name)))
94+
return
95+
}
96+
dispatch(notify(copyQuerySuccess(cell.name)))
97+
}
98+
7999
const popoverContents = (onHide): JSX.Element => {
80100
if (view.properties.type === 'markdown') {
81101
return (
@@ -185,6 +205,15 @@ const CellContext: FC<Props> = ({
185205
onHide={onHide}
186206
testID="cell-context--copy"
187207
/>
208+
{view.properties?.queries?.length && (
209+
<CellContextItem
210+
label="Copy Query"
211+
onClick={handleCopyQuery}
212+
icon={IconFont.Clipboard_New}
213+
onHide={onHide}
214+
testID="cell-context--copy-query"
215+
/>
216+
)}
188217
</div>
189218
)
190219
}

src/shared/copy/notifications/categories/dashboard.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,26 @@ export const removedDashboardLabelFailed = (): Notification => ({
117117
...defaultErrorNotification,
118118
message: 'Failed to remove label from dashboard',
119119
})
120+
121+
export const copyQuerySuccess = (cellName?: string): Notification => {
122+
let fromCellName = ''
123+
if (cellName) {
124+
fromCellName = ` from '${cellName}'`
125+
}
126+
return {
127+
...defaultSuccessNotification,
128+
icon: IconFont.DashH,
129+
message: `The query${fromCellName} was copied to your clipboard.`,
130+
}
131+
}
132+
133+
export const copyQueryFailure = (cellName: string = ''): Notification => {
134+
let fromCellName = '.'
135+
if (cellName) {
136+
fromCellName = ` from '${cellName}.'`
137+
}
138+
return {
139+
...defaultErrorNotification,
140+
message: `There was an error copying the query${fromCellName}. Please try again.`,
141+
}
142+
}

src/types/dashboards.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export type BuilderConfigAggregateWindow = BuilderConfig['aggregateWindow']
3636
export interface Cell extends GenCell {
3737
dashboardID: string
3838
status: RemoteDataState
39+
name?: string
3940
minH?: number
4041
minW?: number
4142
maxW?: number

0 commit comments

Comments
 (0)