@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
JavaScript
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;