-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathExportButton.tsx
More file actions
74 lines (67 loc) · 1.77 KB
/
ExportButton.tsx
File metadata and controls
74 lines (67 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import React, { useState } from "react";
import {
EuiButton,
EuiPopover,
EuiContextMenuPanel,
EuiContextMenuItem,
} from "@elastic/eui";
interface ExportButtonProps {
data: any[];
fileName: string;
formats?: ("json" | "csv")[];
}
const ExportButton: React.FC<ExportButtonProps> = ({
data,
fileName,
formats = ["json", "csv"],
}) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const exportData = (format: "json" | "csv") => {
let content = "";
let mimeType = "";
if (format === "json") {
content = JSON.stringify(data, null, 2);
mimeType = "application/json";
} else {
const headers = Object.keys(data[0] || {}).join(",") + "\n";
const rows = data.map((item) => Object.values(item).join(",")).join("\n");
content = headers + rows;
mimeType = "text/csv";
}
const blob = new Blob([content], { type: mimeType });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = `${fileName}.${format}`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
const exportMenu = (
<EuiContextMenuPanel
items={formats.map((format) => (
<EuiContextMenuItem key={format} onClick={() => exportData(format)}>
Export {format.toUpperCase()}
</EuiContextMenuItem>
))}
/>
);
return (
<EuiPopover
button={
<EuiButton
color="primary"
fill
onClick={() => setIsPopoverOpen(!isPopoverOpen)}
>
Export
</EuiButton>
}
isOpen={isPopoverOpen}
closePopover={() => setIsPopoverOpen(false)}
panelPaddingSize="s"
>
{exportMenu}
</EuiPopover>
);
};
export default ExportButton;