UNPKG

@pagamio/frontend-commons-lib

Version:

Pagamio library for Frontend reusable components like the form engine and table container

95 lines (94 loc) 6.84 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { Stack } from '@mantine/core'; import { Checkbox, Label } from 'flowbite-react'; import { useEffect, useRef, useState } from 'react'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../components'; import { exportToCsv, exportToPdf, exportToXlsx } from './exportUtils'; const ExportDropdown = ({ data, columns, containerClassName, buttonClassName, extraOptions = [], pdfOptions, xlsxOptions, csvOptions, exportAll = false, fetchData, }) => { const [exportType, setExportType] = useState(null); const [excludedColumns, setExcludedColumns] = useState(['action']); const [isExporting, setIsExporting] = useState(false); const [exportAllData, setExportAllData] = useState(false); const [selectOpen, setSelectOpen] = useState(false); const popoverRef = useRef(null); useEffect(() => { const handleClickOutside = (event) => { if (popoverRef.current && !popoverRef.current.contains(event.target)) { setExportType(null); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, []); const exportOptions = [ { value: 'csv', label: 'Export as CSV' }, { value: 'xlsx', label: 'Export as XLSX' }, { value: 'pdf', label: 'Export as PDF' }, ]; const handleCheckboxChange = (columnKey, checked) => { setExcludedColumns((prev) => (checked ? [...prev, columnKey] : prev.filter((key) => key !== columnKey))); }; const getIncludedColumns = () => { return columns.filter((col) => !excludedColumns.includes(col.accessorKey)); }; const handleContinue = async () => { const includedColumns = getIncludedColumns(); setIsExporting(true); try { let exportData = data; // If exportAll is checked and fetchData function is provided, fetch all data if (exportAllData && fetchData) { exportData = await fetchData({ exportAll: 'true' }); } if (exportType === 'csv') { exportToCsv(exportData, includedColumns, csvOptions); } else if (exportType === 'xlsx') { exportToXlsx(exportData, includedColumns, xlsxOptions); } else if (exportType === 'pdf') { // Pass PDF options with enhanced configuration await exportToPdf(exportData, includedColumns, { title: pdfOptions?.title || 'Data Export', subtitle: pdfOptions?.subtitle, colors: pdfOptions?.colors, logo: pdfOptions?.logo, }); } } catch (error) { console.error('Export failed:', error); } finally { setIsExporting(false); setExportType(null); } }; const handleExportChange = (type) => { if (!type || type === 'none') { setExportType(null); return; } // Check if type is an extraOption const extra = extraOptions.find((opt) => opt.value === type); if (extra) { extra.onClick(); setExportType(null); return; } setExportType(type); }; // Show popover when exportType is set and Select is closed const popoverOpened = exportType !== null && !selectOpen; return (_jsxs("div", { className: `w-40 ${containerClassName ?? ''}`, children: [_jsxs(Select, { value: exportType ?? 'none', open: selectOpen, onOpenChange: setSelectOpen, onValueChange: (value) => handleExportChange(value === 'none' ? null : value), children: [_jsx(SelectTrigger, { className: `w-full ${buttonClassName ?? ''}`, children: _jsx(SelectValue, { placeholder: "Export Data" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "none", children: _jsx("span", { className: "text-gray-500", children: "Export Data As" }) }, "reset"), exportOptions.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))), extraOptions.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value)))] })] }, "export-dropdown"), popoverOpened && (_jsxs("div", { ref: popoverRef, className: "mt-2 bg-white rounded-md shadow-lg p-4 z-50 absolute w-45", children: [_jsx("div", { className: "text-sm text-gray-500 pb-3", children: "Uncheck to exclude column from export" }), _jsxs("div", { className: "mb-4 p-3 bg-gray-50 rounded-md", children: [_jsxs("div", { className: "flex items-center gap-x-2", children: [_jsx(Checkbox, { id: "export-all-data", checked: exportAllData, onChange: (event) => setExportAllData(event.currentTarget.checked), className: "checked:!bg-primary-500 checked:!border-primary-500" }), _jsx(Label, { htmlFor: "export-all-data", className: "text-sm font-medium", children: "Export all data" })] }), _jsx("p", { className: "text-xs text-gray-500 mt-1 ml-6", children: "This will fetch all records for the table" })] }), _jsx(Stack, { children: columns.map((col) => { if (col.accessorKey !== 'action') { return (_jsxs("div", { className: "flex items-center gap-x-2", children: [_jsx(Checkbox, { id: col.header, checked: !excludedColumns.includes(col.accessorKey), onChange: (event) => handleCheckboxChange(col.accessorKey, !event.currentTarget.checked), className: "checked:!bg-primary-500 checked:!border-primary-500" }), _jsx(Label, { htmlFor: "rememberMe", children: col.header })] }, col.accessorKey)); } }) }), _jsx("button", { className: `w-full mt-4 px-4 py-2 rounded-md text-white flex items-center justify-center ${getIncludedColumns().length === 0 || isExporting ? 'bg-gray-300 cursor-not-allowed' : 'bg-primary-500 hover:bg-primary-600'}`, onClick: handleContinue, disabled: getIncludedColumns().length === 0 || isExporting, children: isExporting ? (_jsxs(_Fragment, { children: [_jsxs("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "Exporting..."] })) : ('Continue') })] }))] })); }; export default ExportDropdown;