fix: paginate import history and report
This commit is contained in:
@@ -110,6 +110,7 @@ const MONTHS = [
|
||||
];
|
||||
|
||||
const YEARS = Array.from({ length: 5 }, (_, index) => String(new Date().getFullYear() - index));
|
||||
const IMPORT_LOG_PAGE_SIZE = 200;
|
||||
|
||||
function formatAccount(account: Pick<EmailAccount, "userName" | "userEmail" | "emailAddress">) {
|
||||
const owner = account.userName?.trim() || account.userEmail;
|
||||
@@ -139,7 +140,11 @@ function TriggerBadge({ trigger }: { trigger: DetailedImportLog["importTrigger"]
|
||||
export default function History() {
|
||||
const { user } = useAuth();
|
||||
const isAdmin = user?.role === "admin";
|
||||
const { data: logs, isLoading } = trpc.importLogs.getByUser.useQuery();
|
||||
const [page, setPage] = useState(0);
|
||||
const { data: logsPage, isLoading } = trpc.importLogs.getByUser.useQuery({
|
||||
limit: IMPORT_LOG_PAGE_SIZE,
|
||||
offset: page * IMPORT_LOG_PAGE_SIZE,
|
||||
});
|
||||
const { data: emailAccounts, isLoading: accountsLoading } = trpc.emailImportService.getConfiguredAccounts.useQuery(undefined, {
|
||||
enabled: isAdmin,
|
||||
staleTime: 30_000,
|
||||
@@ -148,7 +153,8 @@ export default function History() {
|
||||
const checkAccountNowMutation = trpc.emailImportService.checkAccountNow.useMutation();
|
||||
const utils = trpc.useUtils();
|
||||
|
||||
const detailedLogs = (logs ?? []) as DetailedImportLog[];
|
||||
const detailedLogs = (logsPage?.items ?? []) as DetailedImportLog[];
|
||||
const totalLogs = logsPage?.total ?? 0;
|
||||
const accounts = (emailAccounts ?? []) as EmailAccount[];
|
||||
const configuredAccounts = useMemo(() => accounts.filter((account) => account.isConfigured === 1), [accounts]);
|
||||
|
||||
@@ -329,7 +335,14 @@ export default function History() {
|
||||
<Select value={triggerFilter} onValueChange={(value) => setTriggerFilter(value as TriggerFilter)}><SelectTrigger className="h-8 w-32 bg-white text-sm"><SelectValue placeholder="Déclencheur" /></SelectTrigger><SelectContent><SelectItem value="all">Tout mode</SelectItem><SelectItem value="manual">Manuel</SelectItem><SelectItem value="automatic">Planifié</SelectItem><SelectItem value="unknown">Non tracé</SelectItem></SelectContent></Select>
|
||||
{hasFilters && <Button variant="ghost" size="sm" className="h-8 px-2 text-gray-500" onClick={() => { setYearFilter("all"); setMonthFilter("all"); setSourceFilter("all"); setTriggerFilter("all"); }} title="Réinitialiser les filtres"><X className="h-4 w-4" /></Button>}
|
||||
</div>
|
||||
<span className="ml-auto text-sm text-gray-500">{filteredLogs.length} import{filteredLogs.length > 1 ? "s" : ""} · {counts.totalDetected} facture{counts.totalDetected > 1 ? "s" : ""} détectée{counts.totalDetected > 1 ? "s" : ""}</span>
|
||||
<div className="ml-auto flex items-center gap-2 text-sm text-gray-500">
|
||||
<span>{filteredLogs.length} import{filteredLogs.length > 1 ? "s" : ""} · {counts.totalDetected} facture{counts.totalDetected > 1 ? "s" : ""} détectée{counts.totalDetected > 1 ? "s" : ""}</span>
|
||||
{totalLogs > IMPORT_LOG_PAGE_SIZE && <>
|
||||
<Button variant="outline" size="sm" className="h-8" disabled={page === 0} onClick={() => setPage((current) => current - 1)}>Précédent</Button>
|
||||
<span className="whitespace-nowrap">Page {page + 1}</span>
|
||||
<Button variant="outline" size="sm" className="h-8" disabled={(page + 1) * IMPORT_LOG_PAGE_SIZE >= totalLogs} onClick={() => setPage((current) => current + 1)}>Suivant</Button>
|
||||
</>}
|
||||
</div>
|
||||
</CardContent></Card>
|
||||
|
||||
<Card><CardContent className="overflow-x-auto p-0">
|
||||
|
||||
@@ -41,6 +41,8 @@ type ErrorDetail = {
|
||||
value?: string;
|
||||
};
|
||||
|
||||
const IMPORT_LOG_PAGE_SIZE = 200;
|
||||
|
||||
function parseJson<T>(str: string | null | undefined): T[] {
|
||||
if (!str) return [];
|
||||
try {
|
||||
@@ -59,7 +61,13 @@ function StatusBadge({ imported, duplicates, errors }: { imported: number; dupli
|
||||
}
|
||||
|
||||
export default function ImportReport() {
|
||||
const { data: logs, isLoading } = trpc.importLogs.getByUser.useQuery();
|
||||
const [page, setPage] = useState(0);
|
||||
const { data: logsPage, isLoading } = trpc.importLogs.getByUser.useQuery({
|
||||
limit: IMPORT_LOG_PAGE_SIZE,
|
||||
offset: page * IMPORT_LOG_PAGE_SIZE,
|
||||
});
|
||||
const logs = (logsPage?.items ?? []) as ImportLog[];
|
||||
const totalLogs = logsPage?.total ?? 0;
|
||||
const [yearFilter, setYearFilter] = useState<string>(String(new Date().getFullYear()));
|
||||
const [monthFilter, setMonthFilter] = useState<string>("all");
|
||||
const [statusFilter, setStatusFilter] = useState<string>("all");
|
||||
@@ -319,6 +327,14 @@ export default function ImportReport() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{totalLogs > IMPORT_LOG_PAGE_SIZE && (
|
||||
<div className="mt-3 flex items-center justify-end gap-2 text-xs text-gray-500">
|
||||
<span>{totalLogs.toLocaleString("fr-FR")} journaux</span>
|
||||
<Button size="sm" variant="outline" className="h-8" disabled={page === 0} onClick={() => setPage((current) => current - 1)}>Précédent</Button>
|
||||
<span>Page {page + 1}</span>
|
||||
<Button size="sm" variant="outline" className="h-8" disabled={(page + 1) * IMPORT_LOG_PAGE_SIZE >= totalLogs} onClick={() => setPage((current) => current + 1)}>Suivant</Button>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user