Skip to content

Commit 22a2065

Browse files
authored
fix: Invalid clipboard content for multi-cell copy in data browser (#2882)
1 parent 506f934 commit 22a2065

File tree

1 file changed

+45
-1
lines changed

1 file changed

+45
-1
lines changed

src/dashboard/Data/Browser/DataBrowser.react.js

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import copy from 'copy-to-clipboard';
1010
import BrowserTable from 'dashboard/Data/Browser/BrowserTable.react';
1111
import BrowserToolbar from 'dashboard/Data/Browser/BrowserToolbar.react';
1212
import * as ColumnPreferences from 'lib/ColumnPreferences';
13+
import { dateStringUTC } from 'lib/DateUtils';
14+
import getFileName from 'lib/getFileName';
1315
import React from 'react';
1416
import { ResizableBox } from 'react-resizable';
1517
import styles from './Databrowser.scss';
@@ -18,6 +20,47 @@ import AggregationPanel from '../../../components/AggregationPanel/AggregationPa
1820

1921
const BROWSER_SHOW_ROW_NUMBER = 'browserShowRowNumber';
2022

23+
function formatValueForCopy(value, type) {
24+
if (value === undefined) {
25+
return '';
26+
}
27+
if (value === null) {
28+
return '(null)';
29+
}
30+
switch (type) {
31+
case 'GeoPoint':
32+
if (value && value.latitude !== undefined && value.longitude !== undefined) {
33+
return `(${value.latitude}, ${value.longitude})`;
34+
}
35+
break;
36+
case 'Date':
37+
if (value && value.iso) {
38+
value = new Date(value.iso);
39+
} else if (typeof value === 'string') {
40+
value = new Date(value);
41+
}
42+
if (value instanceof Date && !isNaN(value)) {
43+
return dateStringUTC(value);
44+
}
45+
break;
46+
case 'File':
47+
if (value && typeof value.url === 'function') {
48+
return getFileName(value);
49+
}
50+
break;
51+
case 'Boolean':
52+
return value ? 'True' : 'False';
53+
}
54+
if (typeof value === 'object') {
55+
try {
56+
return JSON.stringify(value);
57+
} catch {
58+
return String(value);
59+
}
60+
}
61+
return String(value);
62+
}
63+
2164
/**
2265
* DataBrowser renders the browser toolbar and data table
2366
* It also manages the fetching / updating of column size prefs,
@@ -304,6 +347,7 @@ export default class DataBrowser extends React.Component {
304347

305348
for (let colIndex = colStart; colIndex <= colEnd; colIndex++) {
306349
const field = this.state.order[colIndex].name;
350+
const type = field === 'objectId' ? 'String' : this.props.columns[field].type;
307351
const value =
308352
field === 'objectId'
309353
? this.props.data[rowIndex].id
@@ -312,7 +356,7 @@ export default class DataBrowser extends React.Component {
312356
if (typeof value === 'number' && !isNaN(value)) {
313357
rowData.push(String(value));
314358
} else {
315-
rowData.push(value || '');
359+
rowData.push(formatValueForCopy(value, type));
316360
}
317361
}
318362

0 commit comments

Comments
 (0)