From 8f8e84cf77f4a7dfad6861aba6dfaff39ac5b918 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Fri, 20 Dec 2024 16:57:30 +0000 Subject: [PATCH] First attempt at full-set-of-failed-records CSV export (#86) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move record-export code out into own function * Provide all records in the result set, not just the currently visible page * This is done using the resource's GET mutator to step through pages * Use mutator.reset after fecthing records Fixes UIHAADM-140, sort of. The problem is that using the stripes-connect GET mutator to iterate through the records somehow affects the state — probably something deep inside the Redux store — in a way that leaves the UI trying to display records that are off the end of the list. I have mitigated this using `mutator.reset()`, which leaves the page blank and looking like it's loading. It's not ideal, but it's not actively wrong. I guess. --- CHANGELOG.md | 1 + src/routes/RecordsRoute.js | 4 ++++ src/views/Records/Records.js | 41 ++++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 447379f..1c91455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Explicit paging for list of failed records. Fixes UIHAADM-141. * Explicit paging for list of harvestables. Fixes UIHAADM-142. +* When downloading Failed Records, provide all records in the result set, not just the currently visible page. Fixes UIHAADM-140. ## [2.2.0](https://github.com/folio-org/ui-harvester-admin/tree/v2.2.0) (2024-10-23) diff --git a/src/routes/RecordsRoute.js b/src/routes/RecordsRoute.js index f4f1ca6..d534972 100644 --- a/src/routes/RecordsRoute.js +++ b/src/routes/RecordsRoute.js @@ -41,6 +41,7 @@ const RecordsRoute = ({ stripes, resources, mutator, children }) => { hasLoaded={hasLoaded} error={error} onNeedMoreData={handleNeedMoreData} + recordsMutator={mutator.records} > {children} @@ -102,6 +103,9 @@ RecordsRoute.propTypes = { query: PropTypes.shape({ update: PropTypes.func.isRequired, }).isRequired, + records: PropTypes.shape({ + GET: PropTypes.func.isRequired, + }).isRequired, }).isRequired, children: PropTypes.object, // XXX may need to add .isRequired later }; diff --git a/src/views/Records/Records.js b/src/views/Records/Records.js index 04dd7c7..3e6ec01 100644 --- a/src/views/Records/Records.js +++ b/src/views/Records/Records.js @@ -11,22 +11,36 @@ import ErrorMessage from '../../components/ErrorMessage'; import packageInfo from '../../../package'; -function renderActionMenu(onToggle, intl, data, renderedColumnsMenu) { +function exportAllRecords(resultCount, recordsMutator) { + const RCI = 100; // Probably keep in sync with RESULT_COUNT_INCREMENT from RecordsRoute.js + + const p = []; + for (let offset = 0; offset < resultCount; offset += RCI) { + p.push(recordsMutator.GET({ params: { offset, limit: RCI } })); + } + + Promise.all(p).then(res => { + recordsMutator.reset(); + const records = res.flat().filter(r => r !== undefined).map(r => ({ + ...r, + errors: errors2string(r.recordErrors), + originalRecord: undefined, + })); + + exportToCsv(records, {}); + }); +} + + +function renderActionMenu(onToggle, intl, data, resultCount, recordsMutator, renderedColumnsMenu) { return (