import * as React from "react";
import { useCallback } from "react";
import { Download } from "lucide-react";
import type { Exporter } from "ra-core";
import {
fetchRelatedRecords,
useDataProvider,
useNotify,
useListContext,
Translate,
} from "ra-core";
import { Button } from "@/components/ui/button";
/**
* A button that exports list data to a file.
*
* Respects current filters and sort order, with configurable maximum results.
* Use a custom exporter to customize the result and fetch related records.
*
* @see {@link https://marmelab.com/shadcn-admin-kit/docs/exportbutton/ ExportButton documentation}
*
* @example
* import { CreateButton, ExportButton, TopToolbar } from '@/components/admin';
*
* const PostListActions = () => (
* <>
*
*
*
* >
* );
*
* export const PostList = () => (
*
}>
* ...
*
* );
*/
export const ExportButton = (props: ExportButtonProps) => {
const {
maxResults = 1000,
onClick,
label = "ra.action.export",
icon = defaultIcon,
exporter: customExporter,
meta,
className = "cursor-pointer",
} = props;
const {
filter,
filterValues,
resource,
sort,
exporter: exporterFromContext,
total,
} = useListContext();
const exporter = customExporter || exporterFromContext;
const dataProvider = useDataProvider();
const notify = useNotify();
const handleClick = useCallback(
(event: React.MouseEvent) => {
dataProvider
.getList(resource, {
sort,
filter: filter ? { ...filterValues, ...filter } : filterValues,
pagination: { page: 1, perPage: maxResults },
meta,
})
.then(
({ data }) =>
exporter &&
exporter(
data,
fetchRelatedRecords(dataProvider),
dataProvider,
resource,
),
)
.catch((error) => {
console.error(error);
notify("HTTP Error", { type: "error" });
});
if (typeof onClick === "function") {
onClick(event);
}
},
[
dataProvider,
exporter,
filter,
filterValues,
maxResults,
notify,
onClick,
resource,
sort,
meta,
],
);
return (
);
};
const defaultIcon = ;
export interface ExportButtonProps {
className?: string;
exporter?: Exporter;
icon?: React.ReactNode;
label?: string;
maxResults?: number;
onClick?: (e: React.MouseEvent) => void;
resource?: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
meta?: any;
}