feat: enhance ExportDropdown and PublicationsTable components for improved export functionality

- Update ExportDropdown to support selected item count and use new icons for formats
- Refactor PublicationsTable to include tri-state checkbox for selection management and year filtering
- Modify DashboardPage to handle selected publication IDs for export
- Adjust API service to support selective export based on publication IDs
This commit is contained in:
Alexis
2026-04-28 12:02:11 +02:00
parent 2bb1309133
commit 63b95fb834
6 changed files with 535 additions and 96 deletions
+19 -4
View File
@@ -36,6 +36,8 @@ export function DashboardPage() {
const [syncStatus, setSyncStatus] = useState("idle"); // idle | loading | success
const [exportingFormat, setExportingFormat] = useState(null);
const [selectedIds, setSelectedIds] = useState(() => new Set());
const loadResearcher = useCallback(
async (signal) => {
try {
@@ -57,7 +59,16 @@ export function DashboardPage() {
setPubsError(null);
try {
const data = await getPublications(orcid, { signal });
if (!signal?.aborted) setPublications(data);
if (!signal?.aborted) {
setPublications(data);
setSelectedIds((prev) => {
if (prev.size === 0) return prev;
const alive = new Set(data.map((p) => p.id));
const next = new Set();
for (const id of prev) if (alive.has(id)) next.add(id);
return next.size === prev.size ? prev : next;
});
}
} catch (err) {
if (signal?.aborted) return;
setPubsError(err);
@@ -89,8 +100,6 @@ export function DashboardPage() {
throw new Error(summary.message || "El backend rechazó la sincronización.");
}
// El backend devuelve un resumen del SyncJob, no el researcher.
// Refrescamos ambos recursos en paralelo.
await Promise.all([loadResearcher(), loadPublications()]);
setSyncStatus("success");
@@ -115,7 +124,10 @@ export function DashboardPage() {
async function handleExport(format) {
setExportingFormat(format);
try {
const { blob, url } = await downloadExport(orcid, format);
const ids = Array.from(selectedIds);
const { blob, url } = await downloadExport(orcid, format, {
publicationIds: ids.length > 0 ? ids : undefined,
});
if (blob) {
const objectUrl = URL.createObjectURL(blob);
const anchor = document.createElement("a");
@@ -152,6 +164,7 @@ export function DashboardPage() {
<ExportDropdown
onExport={handleExport}
exportingFormat={exportingFormat}
selectedCount={selectedIds.size}
/>
</>
}
@@ -167,6 +180,8 @@ export function DashboardPage() {
loading={pubsLoading}
error={pubsError}
onRetry={() => loadPublications()}
selectedIds={selectedIds}
onSelectedIdsChange={setSelectedIds}
/>
<footer className="mt-4 flex flex-wrap items-center justify-between gap-2 px-1">