import { useEffect, useState, type ChangeEvent, type MouseEvent, type ReactElement } from "react";
import {
DataTable,
DataTableBody,
DataTableEmpty,
DataTableHeader
} from "../../ui/DataTable";
import { Toolbar, ToolbarGroup, ToolbarSearch } from "../../ui/Toolbar";
import { SlidingSelection } from "../../ui/SlidingSelection";
import { paginateHistoryRows, type HistoryFilter, type HistoryPage, type HistoryRow, type HistoryViewModel } from "./history-model";
import "./history.css";
export interface HistoryViewActions {
onFilterChange: (filter: HistoryFilter) => void;
onQueryChange: (value: string) => void;
onToggleSelection: (entryId: string) => void;
onToggleSelectAll: (visibleIds: string[]) => void;
onToggleExpansion: (entryId: string) => void;
onRestore: (entryIds: string[]) => void;
onReveal: (entryId: string) => void;
onRemove: (entryIds: string[]) => void;
onClearSelection: () => void;
onClearHistory: () => void;
onContextMenu: (entryId: string, x: number, y: number) => void;
}
export interface HistoryViewProps {
model: HistoryViewModel;
actions: HistoryViewActions;
}
const filterItems: Array<{ id: HistoryFilter; label: string }> = [
{ id: "all", label: "Alle Einträge" },
{ id: "today", label: "Heute" },
{ id: "week", label: "Letzte 7 Tage" },
{ id: "older", label: "Älter" },
{ id: "completed", label: "Fertig" },
{ id: "deleted", label: "Gelöscht" },
{ id: "failed", label: "Fehlgeschlagen" }
];
function HistoryRowDetails({ row }: { row: HistoryRow }): ReactElement {
return (
- Provider
- {row.providerLabel}
- Dateien
- {row.fileCount}
- Dauer
- {row.durationLabel}
- Durchschnitt
- {row.averageSpeedLabel}
- Zielordner
- {row.outputDir || "—"}
- URLs
- {row.urls?.length ? row.urls.join("\n") : "—"}
);
}
export function HistorySidebar({ model, actions }: HistoryViewProps): ReactElement {
return (
Verlauf
{filterItems.map((item) => (
))}
);
}
export function HistoryToolbar({ model, actions }: HistoryViewProps): ReactElement {
const selectedIds = model.selectedIds;
const selectedSet = new Set(selectedIds);
const restorable = model.rows.some((row) => selectedSet.has(row.id) && (row.urls?.length ?? 0) > 0);
return (
) => actions.onQueryChange(event.target.value)}
placeholder="Name, Pfad, Hoster oder Provider"
value={model.query}
/>
);
}
export function historyPageStatusLabel(page: HistoryPage): string {
return `Seite ${page.page} von ${page.totalPages}`;
}
export function HistoryPagination({
page,
onPageChange
}: {
page: HistoryPage;
onPageChange: (page: number) => void;
}): ReactElement {
return (
);
}
interface HistoryContentPageProps extends HistoryViewProps {
page: HistoryPage;
onPageChange: (page: number) => void;
}
export function HistoryContentPage({ model, actions, page, onPageChange }: HistoryContentPageProps): ReactElement {
const selected = new Set(model.selectedIds);
const expanded = new Set(model.expandedIds);
const visibleIds = page.rows.map((row) => row.id);
const allVisibleSelected = visibleIds.length > 0 && visibleIds.every((id) => selected.has(id));
const showEmpty = !model.loading && !model.error && model.rows.length === 0;
const emptyTitle = model.totalCount === 0 && !model.query && model.filter === "all"
? "Noch kein Verlauf"
: "Keine passenden Einträge";
const announcement = model.loading
? { role: "status" as const, live: "polite" as const, message: "Verlauf wird geladen. Die gespeicherten Einträge werden geladen." }
: model.error
? { role: "alert" as const, live: "assertive" as const, message: `${model.error}. Öffne die Ansicht erneut, um es noch einmal zu versuchen.` }
: null;
return (
);
}
function PaginatedHistoryContent({ model, actions }: HistoryViewProps): ReactElement {
const [requestedPage, setRequestedPage] = useState(1);
const page = paginateHistoryRows(model.rows, requestedPage);
useEffect(() => {
setRequestedPage((current) => current === page.page ? current : page.page);
}, [page.page]);
return (
);
}
export function HistoryContent({ model, actions }: HistoryViewProps): ReactElement {
return ;
}
export function HistoryFooter(_props: Pick): null {
return null;
}
export function HistoryView({ model, actions }: HistoryViewProps): ReactElement {
return (
);
}