diff --git a/src/components/BulkEditPane/BulkEditInAppLayer/BulkEditInAppLayer.js b/src/components/BulkEditPane/BulkEditInAppLayer/BulkEditInAppLayer.js index 84f1226f..94254de9 100644 --- a/src/components/BulkEditPane/BulkEditInAppLayer/BulkEditInAppLayer.js +++ b/src/components/BulkEditPane/BulkEditInAppLayer/BulkEditInAppLayer.js @@ -29,6 +29,7 @@ export const BulkEditInAppLayer = ({ downloadFile, confirmChanges, closePreviewModal, + setShouldRefetchStatus } = useConfirmChanges({ queryDownloadKey: QUERY_KEY_DOWNLOAD_PREVIEW_MODAL, updateFn: contentUpdate, @@ -81,6 +82,7 @@ export const BulkEditInAppLayer = ({ onDownload={downloadFile} onKeepEditing={closePreviewModal} onChangesCommited={handleChangesCommited} + setShouldRefetchStatus={setShouldRefetchStatus} /> ); diff --git a/src/components/BulkEditPane/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditPreviewModal.js b/src/components/BulkEditPane/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditPreviewModal.js index 6e89470e..8281094c 100644 --- a/src/components/BulkEditPane/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditPreviewModal.js +++ b/src/components/BulkEditPane/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditPreviewModal.js @@ -27,6 +27,7 @@ export const BulkEditPreviewModal = ({ onKeepEditing, onDownload, onChangesCommited, + setShouldRefetchStatus }) => { const callout = useShowCallout(); const intl = useIntl(); @@ -91,6 +92,7 @@ export const BulkEditPreviewModal = ({ bulkDetails={bulkDetails} isPreviewEnabled={!isPreviewLoading} onPreviewError={onKeepEditing} + setShouldRefetchStatus={setShouldRefetchStatus} /> ); @@ -103,4 +105,5 @@ BulkEditPreviewModal.propTypes = { onKeepEditing: PropTypes.func, onChangesCommited: PropTypes.func, onDownload: PropTypes.func, + setShouldRefetchStatus: PropTypes.func }; diff --git a/src/components/BulkEditPane/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditPreviewModalList.js b/src/components/BulkEditPane/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditPreviewModalList.js index d84f124c..408bb8e4 100644 --- a/src/components/BulkEditPane/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditPreviewModalList.js +++ b/src/components/BulkEditPane/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditPreviewModalList.js @@ -1,4 +1,8 @@ -import React, { useContext } from 'react'; +import React, { + useContext, + useEffect, + useState +} from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage, @@ -40,6 +44,7 @@ export const BulkEditPreviewModalList = ({ bulkDetails, isPreviewEnabled, onPreviewError, + setShouldRefetchStatus, }) => { const callout = useShowCallout(); const intl = useIntl(); @@ -52,6 +57,15 @@ export const BulkEditPreviewModalList = ({ } = usePagination(PAGINATION_CONFIG); const visibleColumnKeys = getVisibleColumnsKeys(visibleColumns); + const [shouldFetch, setShouldFetch] = useState(false); + + useEffect(() => { + if (isPreviewEnabled && ![JOB_STATUSES.DATA_MODIFICATION_IN_PROGRESS, JOB_STATUSES.DATA_MODIFICATION].includes(bulkDetails?.status)) { + setShouldFetch(true); + } else { + setShouldFetch(false); + } + }, [bulkDetails?.status, isPreviewEnabled]); const { contentData, @@ -62,8 +76,9 @@ export const BulkEditPreviewModalList = ({ id: bulkDetails?.id, step: EDITING_STEPS.EDIT, capabilities: currentRecordType, + onSuccess: () => setShouldRefetchStatus(false), queryOptions: { - enabled: isPreviewEnabled && bulkDetails?.status !== JOB_STATUSES.DATA_MODIFICATION_IN_PROGRESS, + enabled: shouldFetch, onSuccess: showErrorMessage, onError: () => { callout({ @@ -137,4 +152,5 @@ BulkEditPreviewModalList.propTypes = { bulkDetails: PropTypes.object, isPreviewEnabled: PropTypes.bool, onPreviewError: PropTypes.func, + setShouldRefetchStatus: PropTypes.func, }; diff --git a/src/components/shared/ProgressBar/ProgressBar.js b/src/components/shared/ProgressBar/ProgressBar.js index 1dc9ad68..24aa5609 100644 --- a/src/components/shared/ProgressBar/ProgressBar.js +++ b/src/components/shared/ProgressBar/ProgressBar.js @@ -24,6 +24,7 @@ export const ProgressBar = () => { const { bulkDetails, clearIntervalAndRedirect } = useBulkOperationDetails({ id, interval: 1000 * 3, + shouldRefetch: true, additionalQueryKeys: [step], }); diff --git a/src/hooks/api/useBulkOperationDetails.js b/src/hooks/api/useBulkOperationDetails.js index 35ff3628..ad7f6ba8 100644 --- a/src/hooks/api/useBulkOperationDetails.js +++ b/src/hooks/api/useBulkOperationDetails.js @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useQuery } from 'react-query'; import { useNamespace, useOkapiKy } from '@folio/stripes/core'; import { useHistory } from 'react-router-dom'; @@ -12,56 +12,62 @@ export const useBulkOperationDetails = ({ id, interval = 0, additionalQueryKeys = [], + shouldRefetch = false, ...options }) => { const ky = useOkapiKy(); const [namespaceKey] = useNamespace({ key: BULK_OPERATION_DETAILS_KEY }); const history = useHistory(); - const [refetchInterval, setRefetchInterval] = useState(interval); + const [refetchInterval, setRefetchInterval] = useState(0); const { showErrorMessage } = useErrorMessages(); - const clearInterval = () => { - setRefetchInterval(0); - }; + const stopRefetching = () => setRefetchInterval(0); - const clearIntervalAndRedirect = (pathname, searchParams) => { - clearInterval(); + const fetchBulkOperationDetails = async () => { + try { + const response = await ky.get(`bulk-operations/${id}`).json(); + showErrorMessage(response); - history.replace({ - pathname, - search: searchParams ? buildSearch(searchParams, history.location.search) : '', - }); + if (response.status === JOB_STATUSES.FAILED || response?.errorMessage) { + stopRefetching(); + } + + return response; + } catch (error) { + showErrorMessage(error); + stopRefetching(); + + return error; + } }; - const { data, isLoading } = useQuery({ - queryKey: [BULK_OPERATION_DETAILS_KEY, namespaceKey, id, refetchInterval, ...additionalQueryKeys], + const { data, isLoading, refetch } = useQuery({ + queryKey: [BULK_OPERATION_DETAILS_KEY, namespaceKey, refetchInterval, id, ...additionalQueryKeys], enabled: !!id, - refetchInterval, - queryFn: async () => { - try { - const response = await ky.get(`bulk-operations/${id}`).json(); + queryFn: fetchBulkOperationDetails, + ...options, + }); - showErrorMessage(response); + useEffect(() => { + if (!shouldRefetch || interval <= 0) return; - if (response.status === JOB_STATUSES.FAILED || response?.errorMessage) { - clearInterval(); - } + const intervalId = setInterval(refetch, interval); - return response; - } catch (e) { - showErrorMessage(e); - clearInterval(); + return () => clearInterval(intervalId); + }, [shouldRefetch, interval, refetch]); - return e; - } - }, - ...options, - }); + const redirectAndStopRefetching = (pathname, searchParams) => { + stopRefetching(); + history.replace({ + pathname, + search: searchParams ? buildSearch(searchParams, history.location.search) : '', + }); + }; return { bulkDetails: data, isLoading, - clearInterval, - clearIntervalAndRedirect, + refetch, + clearIntervalAndRedirect: redirectAndStopRefetching, }; }; diff --git a/src/hooks/api/useBulkOperationDetails.test.js b/src/hooks/api/useBulkOperationDetails.test.js index e4df975b..b8d20a6b 100644 --- a/src/hooks/api/useBulkOperationDetails.test.js +++ b/src/hooks/api/useBulkOperationDetails.test.js @@ -49,15 +49,13 @@ describe('useBulkOperationDetails', () => { it('should initialize with the correct refetch interval and query key', () => { const id = 'test-id'; - const refetchInterval = 5000; + const interval = 5000; - const { result } = renderHook(() => useBulkOperationDetails({ id, interval: refetchInterval })); + renderHook(() => useBulkOperationDetails({ id, interval })); - expect(result.current.isLoading).toBe(false); expect(useQuery).toHaveBeenCalledWith( expect.objectContaining({ - queryKey: [BULK_OPERATION_DETAILS_KEY, 'namespace-key', id, refetchInterval], - refetchInterval, + queryKey: [BULK_OPERATION_DETAILS_KEY, 'namespace-key', 0, id], enabled: true, }) ); diff --git a/src/hooks/api/useRecordsPreview.js b/src/hooks/api/useRecordsPreview.js index e53e59cb..4894c07e 100644 --- a/src/hooks/api/useRecordsPreview.js +++ b/src/hooks/api/useRecordsPreview.js @@ -4,6 +4,7 @@ import { useIntl } from 'react-intl'; import { useNamespace, useOkapiKy } from '@folio/stripes/core'; +import noop from 'lodash/noop'; import { BULK_VISIBLE_COLUMNS } from '../../constants'; import { getMappedTableData } from '../../utils/mappers'; import { RootContext } from '../../context/RootContext'; @@ -21,7 +22,8 @@ export const useRecordsPreview = ({ limit, offset, criteria, - queryRecordType + queryRecordType, + onSuccess = noop, }) => { const intl = useIntl(); const { setVisibleColumns } = useContext(RootContext); @@ -83,6 +85,12 @@ export const useRecordsPreview = ({ capabilities ]); + useEffect(() => { + if (contentData?.length > 0) { + onSuccess(); + } + }, [contentData, onSuccess]); + return { isLoading, refetch, diff --git a/src/hooks/useConfirmChanges.js b/src/hooks/useConfirmChanges.js index a65e0a6d..5e384d9c 100644 --- a/src/hooks/useConfirmChanges.js +++ b/src/hooks/useConfirmChanges.js @@ -5,7 +5,6 @@ import { useQueryClient } from 'react-query'; import { useShowCallout } from '@folio/stripes-acq-components'; import { - PREVIEW_MODAL_KEY, BULK_OPERATION_DETAILS_KEY, useBulkOperationDetails, useBulkOperationStart, @@ -32,8 +31,13 @@ export const useConfirmChanges = ({ const [isPreviewModalOpened, setIsPreviewModalOpened] = useState(false); const [isPreviewLoading, setIsPreviewLoading] = useState(false); + const [shouldRefetchStatus, setShouldRefetchStatus] = useState(false); - const { bulkDetails } = useBulkOperationDetails({ id: bulkOperationId, interval: 1000 * 3 }); + const { bulkDetails } = useBulkOperationDetails({ + id: bulkOperationId, + interval: 1000 * 3, + shouldRefetch: shouldRefetchStatus, + }); const { bulkOperationStart } = useBulkOperationStart(); const totalRecords = bulkDetails?.totalNumOfRecords; @@ -44,11 +48,13 @@ export const useConfirmChanges = ({ const closePreviewModal = () => { setIsPreviewModalOpened(false); + setShouldRefetchStatus(false); }; const confirmChanges = (payload) => { setIsPreviewLoading(true); setIsPreviewModalOpened(true); + setShouldRefetchStatus(true); updateFn(payload) .then(() => bulkOperationStart({ @@ -58,7 +64,6 @@ export const useConfirmChanges = ({ })) .then(() => { queryClient.invalidateQueries(BULK_OPERATION_DETAILS_KEY); - queryClient.invalidateQueries(PREVIEW_MODAL_KEY); }) .catch(() => { callout({ @@ -94,5 +99,6 @@ export const useConfirmChanges = ({ openPreviewModal, closePreviewModal, confirmChanges, + setShouldRefetchStatus }; };