Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UIBULKED-210: Improve user errors for invalid data - IncorrectTokenCo… #482

Merged
merged 8 commits into from
Feb 19, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@
onSuccess: fileData => {
const searchParams = new URLSearchParams(history.location.search);
let fileName = searchParams.get('fileName');
const criteria = searchParams.get('criteria');

if (!fileName) {
fileName = `${currentRecordType}-${searchParams.get('criteria')}.csv`;
fileName = `${criteria.charAt(0).toUpperCase().toUpperCase() + criteria.slice(1)}-${bulkOperationId}.csv`;
}

saveAs(new Blob([fileData]), `${getFormattedFilePrefixDate()}-Updates-Preview-${fileName}`);
Expand Down Expand Up @@ -161,7 +162,7 @@
setIsLoadingPreview(false);
});
}
}, [contentUpdates, open, totalRecords]);

Check warning on line 165 in src/components/BulkEditList/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditInAppPreviewModal.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

React Hook useEffect has missing dependencies: 'bulkOperationId', 'bulkOperationStart', 'contentUpdate', 'onKeepEditing', 'queryClient', and 'swwCallout'. Either include them or remove the dependency array. If 'onKeepEditing' changes too often, find the parent component that defines it and wrap that definition in useCallback

Check warning on line 165 in src/components/BulkEditList/BulkEditListResult/BulkEditInAppPreviewModal/BulkEditInAppPreviewModal.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

React Hook useEffect has missing dependencies: 'bulkOperationId', 'bulkOperationStart', 'contentUpdate', 'onKeepEditing', 'queryClient', and 'swwCallout'. Either include them or remove the dependency array. If 'onKeepEditing' changes too often, find the parent component that defines it and wrap that definition in useCallback

return (
<Modal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { QueryClientProvider } from 'react-query';
import { MemoryRouter } from 'react-router';

import { act, render, screen, fireEvent } from '@testing-library/react';
import {
act,
render,
screen,
fireEvent
} from '@testing-library/react';

import { useOkapiKy } from '@folio/stripes/core';

Expand Down Expand Up @@ -42,9 +47,9 @@ const defaultProps = {
contentUpdates: undefined,
};

const renderPreviewModal = (props = defaultProps) => {
const renderPreviewModal = (props = defaultProps, fileName = 'barcodes.csv') => {
return render(
<MemoryRouter initialEntries={['/bulk-edit/1/initial?capabilities=ITEMS&fileName=barcodes.csv&identifier=BARCODE']}>
<MemoryRouter initialEntries={[`/bulk-edit/1/initial?capabilities=ITEMS&fileName=${fileName}&identifier=BARCODE`]}>
<QueryClientProvider client={queryClient}>
<RootContext.Provider value={{
visibleColumns,
Expand Down Expand Up @@ -94,6 +99,12 @@ describe('BulkEditInAppPreviewModal', () => {
expect(onKeepEditing).toHaveBeenCalled();
});

it('should call all footer handlers without fileName', () => {
renderPreviewModal(defaultProps, '');

fireEvent.click(screen.getByText('ui-bulk-edit.previewModal.downloadPreview'));
});

it('should display preview records when available', async () => {
const contentUpdates = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
} from '@folio/stripes/components';
import { useState } from 'react';
import css from '../Preview.css';
import { useSearchParams } from '../../../../../hooks/useSearchParams';
import { CRITERIA } from '../../../../../constants';

const visibleColumns = ['key', 'message'];

Expand All @@ -29,24 +31,37 @@ const ErrorsAccordion = ({
isInitial,
}) => {
const location = useLocation();
const { criteria } = useSearchParams();
const fileName = new URLSearchParams(location.search).get('fileName');
const errorLength = errors.length;

const [opened, setOpened] = useState(!!errorLength);

const headLineTranslateKey = isInitial ? 'info' : 'infoProcessed';

const headLine = (
<FormattedMessage
id={`ui-bulk-edit.list.errors.${headLineTranslateKey}`}
values={{
fileName,
entries,
matched,
errors: countOfErrors,
}}
/>
);
const headLine = criteria === CRITERIA.QUERY ?
(
<FormattedMessage
id={`ui-bulk-edit.list.errors.query.${headLineTranslateKey}`}
values={{
entries,
matched,
errors: countOfErrors,
}}
/>
)
:
(
<FormattedMessage
id={`ui-bulk-edit.list.errors.${headLineTranslateKey}`}
values={{
fileName,
entries,
matched,
errors: countOfErrors,
}}
/>
);

return (
<div className={css.previewAccordion}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ describe('ErrorsAccordion', () => {
expect(screen.getByText(errorsPreview.errors[0].message)).toBeVisible();
});

it('should render preview accordion for bulk edit query', () => {
const mockHistory = ['/bulk-edit/1/preview?criteria=query'];

renderPreviewAccordion(mockHistory, { ...defaultProps, initial: true });

expect(screen.getByText(/errors.query.info/)).toBeVisible();
expect(screen.getByText(/errors.table.code/)).toBeVisible();
expect(screen.getByText(errorsPreview.errors[0].message)).toBeVisible();
});

it('should render with no axe errors', async () => {
const mockHistory = ['/bulk-edit/1/preview'];

Expand Down
9 changes: 6 additions & 3 deletions src/components/ProgressBar/ProgressBar.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useContext, useEffect } from 'react';
import React, { useContext, useEffect } from 'react';
import { useParams } from 'react-router';
import { useLocation } from 'react-router-dom';
import { FormattedMessage, useIntl } from 'react-intl';
Expand All @@ -8,7 +8,7 @@
import { useShowCallout } from '@folio/stripes-acq-components';

import { useBulkOperationDetails } from '../../hooks/api';
import { JOB_STATUSES } from '../../constants';
import { ERRORS, JOB_STATUSES } from '../../constants';
import { getBulkOperationStep } from './utils';

import css from './ProgressBar.css';
Expand All @@ -33,14 +33,17 @@
});

const status = bulkDetails?.status;
const errorMessage = bulkDetails?.errorMessage;
const progressPercentage = bulkDetails
? (bulkDetails.processedNumOfRecords / bulkDetails.totalNumOfRecords) * 100
: 0;

const swwCallout = () => {
callout({
type: 'error',
message: intl.formatMessage({ id: 'ui-bulk-edit.error.sww' }),
message: errorMessage?.includes(ERRORS.TOKEN) ? <FormattedMessage id="ui-bulk-edit.error.incorrectFormatted" values={{ fileName:title }} />
:
intl.formatMessage({ id: 'ui-bulk-edit.error.sww' }),
});
};

Expand All @@ -55,7 +58,7 @@
swwCallout();
clearIntervalAndRedirect('/bulk-edit', '');
}
}, [status]);

Check warning on line 61 in src/components/ProgressBar/ProgressBar.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

React Hook useEffect has missing dependencies: 'bulkDetails', 'clearIntervalAndRedirect', 'id', and 'swwCallout'. Either include them or remove the dependency array

Check warning on line 61 in src/components/ProgressBar/ProgressBar.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

React Hook useEffect has missing dependencies: 'bulkDetails', 'clearIntervalAndRedirect', 'id', and 'swwCallout'. Either include them or remove the dependency array

return (
<div className={css.progressBar}>
Expand Down
19 changes: 18 additions & 1 deletion src/components/ProgressBar/ProgressBar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { render, screen } from '@testing-library/react';

import { runAxeTest } from '@folio/stripes-testing';

import { JOB_STATUSES } from '../../constants';
import { ERRORS, JOB_STATUSES } from '../../constants';
import { useBulkOperationDetails } from '../../hooks/api';

import { ProgressBar } from './ProgressBar';
Expand Down Expand Up @@ -33,6 +33,7 @@ describe('ProgressBar', () => {
totalNumOfRecords: 100,
status: JOB_STATUSES.APPLY_CHANGES,
};

const clearIntervalAndRedirect = jest.fn();

beforeEach(() => {
Expand Down Expand Up @@ -108,3 +109,19 @@ describe('ProgressBar', () => {
});
});
});

describe('test', () => {
const bulkOperationWithError = {
processedNumOfRecords: 50,
totalNumOfRecords: 100,
status: JOB_STATUSES.FAILED,
errorMessage: ERRORS.TOKEN
};

it('should render with error', async () => {
useBulkOperationDetails.mockClear().mockReturnValue({ bulkDetails: bulkOperationWithError,
clearIntervalAndRedirect: jest.fn() });

renderProgressBar();
});
});
2 changes: 2 additions & 0 deletions translations/ui-bulk-edit/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
"list.errors.title": "Errors",
"list.errors.info": "<b>{fileName}: {entries, number} entries * {matched, number} records matched * {errors, number} errors</b>",
"list.errors.infoProcessed": "<b>{fileName}: {entries, number} entries * {matched, number} records changed * {errors, number} errors</b>",
"list.errors.query.info": "<b>Bulk edit query: {entries, number} entries * {matched, number} records matched * {errors, number} errors</b>",
"list.errors.query.infoProcessed": "<b>Bulk edit query: {entries, number} entries * {matched, number} records changed * {errors, number} errors</b>",
"list.errors.table.code": "Record identifier",
"list.errors.table.message": "Reason for error",

Expand Down
Loading