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

UIDATIMP-1443: Improve mapping profile for Holdings for handling multiple Holdings mapping #1404

Closed
wants to merge 9 commits into from
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
* Invoice field mapping: Add info icon to the Acq unit field (UIDATIMP-1427)
* View all: Create hotlink from job profile name in log to the job profile details (UIDATIMP-1428)
* Fix warnings in unit tests (part 2) (UIDATIMP-1437)
* Update Log JSON screen to support multiple holdings (UIDATIMP-1439)
* Update Log JSON screen to support multiple items (UIDATIMP-1440)
* Improve mapping profile for Holdings for handling multiple Holdings mapping (UIDATIMP-1443)
* DI Log: change Discarded to No action (UIDATIMP-1446)
* DI Log: Make some changes to the Log header (UIDATIMP-1447)
* DI Job profiles: Redirect when job profile was deleted (UIDATIMP-1450)
Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './useInventoryItemsByIdQuery';
export * from './useInvoiceLineByIdQuery';
export * from './useInvoicesByIdQuery';
export * from './useJobLogRecordsQuery';
export * from './useLocationsQuery';
export * from './useOrderByIdQuery';
export * from './usePOLinesByIdQuery';
export * from './useSRSRecordQuery';
31 changes: 31 additions & 0 deletions src/hooks/tests/useLocationsQuery.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { renderHook } from '@testing-library/react-hooks';

import '../../../test/jest/__mock__';

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

import { useLocationsQuery } from '../useLocationsQuery';
import { queryClientWrapper } from '../../../test/jest/helpers';

const mockLocationsRecord = [{ id: 'locationId1' }, { id: 'locationId2' }];

describe('useLocationsQuery', () => {
beforeEach(() => {
useOkapiKy.mockClear().mockReturnValue({
get: () => {
return ({
json: () => Promise.resolve({ locations: mockLocationsRecord })
});
},
});
});

it('should fetch locations', async () => {
const { result, waitFor } = renderHook(() => useLocationsQuery(), { wrapper: queryClientWrapper });

await waitFor(() => !result.current.isLoading);

expect(result.current.data).toEqual(mockLocationsRecord);
});
});
21 changes: 21 additions & 0 deletions src/hooks/useLocationsQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useQuery } from 'react-query';

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

export const useLocationsQuery = () => {
const ky = useOkapiKy();
const [namespace] = useNamespace({ key: 'locations' });

const query = useQuery({
queryKey: [namespace],
queryFn: () => ky.get('locations').json(),
});

return ({
...query,
data: query.data?.locations,
});
};
236 changes: 145 additions & 91 deletions src/routes/ViewJobLog.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {
useEffect,
useMemo,
useState,
} from 'react';
import { FormattedMessage } from 'react-intl';
Expand All @@ -25,6 +26,7 @@ import {
useInvoicesByIdQuery,
useInvoiceLineByIdQuery,
useAuthoritiesByIdQuery,
useLocationsQuery,
} from '../hooks';

import {
Expand Down Expand Up @@ -65,6 +67,7 @@ export const ViewJobLog = () => {
const { data: invoicesData } = useInvoicesByIdQuery(invoicesIds);
const { data: invoiceLineData } = useInvoiceLineByIdQuery(invoiceLineId);
const { data: authoritiesData } = useAuthoritiesByIdQuery(authoritiesIds);
const { data: locationsData = [] } = useLocationsQuery();

useEffect(() => {
if (!isJobLogLoading && !isJobLogError) {
Expand All @@ -79,8 +82,8 @@ export const ViewJobLog = () => {
} = jobLogData;

setInstancesIds(relatedInstanceInfo.idList);
setHoldingsIds(relatedHoldingsInfo.idList);
setItemsIds(relatedItemInfo.idList);
setHoldingsIds(relatedHoldingsInfo.map((item) => item.id).filter((id) => !!id));
setItemsIds(relatedItemInfo.map((item) => item.id).filter((id) => !!id));
setOrderId(relatedPoLineInfo?.orderId);
setPoLinesIds(relatedPoLineInfo?.idList);
setInvoicesIds(relatedInvoiceInfo.idList);
Expand All @@ -89,35 +92,145 @@ export const ViewJobLog = () => {
}
}, [isJobLogLoading, isJobLogError, jobLogData]);

const getErrorMessage = entityOption => {
if (isJobLogLoading || isJobLogError) return '';
const srsMarcBibLogs = useMemo(() => {
const { error } = jobLogData;

return [
{
label: '',
logs: srsRecordData,
error: error || '',
errorBlockId: 'srs-marc-bib-error',
},
];
}, [jobLogData, srsRecordData]);
const instanceLogs = useMemo(() => {
const { relatedInstanceInfo } = jobLogData;

return [
{
label: '',
logs: instancesData,
error: relatedInstanceInfo?.error || '',
errorBlockId: 'instance-error',
},
];
}, [instancesData, jobLogData]);
const holdingsLogs = useMemo(() => {
const { relatedHoldingsInfo } = jobLogData;

const getHoldingsLabel = (holding = {}) => {
const { permanentLocationId } = holding;

if (!permanentLocationId) return '';

const permanentLocation = locationsData.find(
(location) => location.id === permanentLocationId
);

return (
<Headline margin="none" className={sharedCss.leftMargin}>
{permanentLocation?.code}
</Headline>
);
};

return (
relatedHoldingsInfo?.map((holding) => ({
label: getHoldingsLabel(holding),
logs: holdingsData?.find((data) => data.id === holding.id),
error: holding.error || '',
errorBlockId: 'holdings-error',
})) || [{ logs: [] }]
);
}, [holdingsData, jobLogData, locationsData]);
const itemsLogs = useMemo(() => {
const { relatedItemInfo } = jobLogData;

const getItemsLabel = (item = {}) => {
const { hrid } = item;

if (!hrid) return '';

return (
<Headline margin="none" className={sharedCss.leftMargin}>
{hrid}
</Headline>
);
};

return (
relatedItemInfo?.map((item) => ({
label: getItemsLabel(item),
logs: itemsData?.find((data) => data.id === item.id),
error: item.error || '',
errorBlockId: 'item-error',
})) || [{ logs: [] }]
);
}, [itemsData, jobLogData]);
const authorityLogs = useMemo(() => {
const { relatedAuthorityInfo } = jobLogData;

return [{
label: '',
logs: authoritiesData,
error: relatedAuthorityInfo?.error || '',
errorBlockId: 'authority-error',
}];
}, [authoritiesData, jobLogData]);
const orderLogs = useMemo(() => {
const { relatedPoLineInfo } = jobLogData;

return [
{
label: (
<Headline margin="none" className={sharedCss.leftMargin}>
<FormattedMessage id="ui-data-import.logViewer.orderLine" />
</Headline>
),
logs: poLinesData,
error: relatedPoLineInfo?.error || '',
errorBlockId: 'order-line-error',
},
{
label: (
<Headline margin="none" className={sharedCss.leftMargin}>
<FormattedMessage id="ui-data-import.logViewer.order" />
</Headline>
),
logs: orderData,
},
];
}, [jobLogData, orderData, poLinesData]);
const invoiceLogs = useMemo(() => {
const {
error,
relatedInstanceInfo,
relatedHoldingsInfo,
relatedItemInfo,
relatedAuthorityInfo,
relatedPoLineInfo,
relatedInvoiceInfo,
relatedInvoiceLineInfo,
relatedInvoiceInfo,
} = jobLogData;

const errors = {
[OPTIONS.SRS_MARC_BIB]: error || '',
[OPTIONS.INSTANCE]: relatedInstanceInfo.error || '',
[OPTIONS.HOLDINGS]: relatedHoldingsInfo.error || '',
[OPTIONS.ITEM]: relatedItemInfo.error || '',
[OPTIONS.ORDER]: relatedPoLineInfo.error || '',
[OPTIONS.AUTHORITY]: relatedAuthorityInfo.error || '',
[OPTIONS.INVOICE]: {
invoiceInfo: relatedInvoiceInfo.error || '',
invoiceLineInfo: relatedInvoiceLineInfo?.error || '',
return [
{
label: (
<Headline margin="none" className={sharedCss.leftMargin}>
<FormattedMessage id="ui-data-import.logViewer.invoiceLine" />
</Headline>
),
logs: invoiceLineData,
error: relatedInvoiceLineInfo?.error || '',
errorBlockId: 'invoice-line-error',
},
};

return errors[entityOption];
};
{
label: (
<Headline margin="none" className={sharedCss.leftMargin}>
<FormattedMessage id="ui-data-import.logViewer.invoice" />
</Headline>
),
logs: invoicesData,
error: relatedInvoiceInfo?.error || '',
errorBlockId: 'invoice-error',
},
];
}, [invoiceLineData, invoicesData, jobLogData]);

if (isJobLogLoading) {
return (
Expand Down Expand Up @@ -155,72 +268,13 @@ export const ViewJobLog = () => {
};

const logs = {
[OPTIONS.SRS_MARC_BIB]: [{
label: '',
logs: srsRecordData,
error: getErrorMessage(OPTIONS.SRS_MARC_BIB),
errorBlockId: 'srs-marc-bib-error',
}],
[OPTIONS.INSTANCE]: [{
label: '',
logs: instancesData,
error: getErrorMessage(OPTIONS.INSTANCE),
errorBlockId: 'instance-error',
}],
[OPTIONS.HOLDINGS]: [{
label: '',
logs: holdingsData,
error: getErrorMessage(OPTIONS.HOLDINGS),
errorBlockId: 'holdings-error',
}],
[OPTIONS.ITEM]: [{
label: '',
logs: itemsData,
error: getErrorMessage(OPTIONS.ITEM),
errorBlockId: 'item-error',
}],
[OPTIONS.AUTHORITY]: [{
label: '',
logs: authoritiesData,
error: getErrorMessage(OPTIONS.AUTHORITY),
errorBlockId: 'authority-error',
}],
[OPTIONS.ORDER]: [{
label: (
<Headline margin="none" className={sharedCss.leftMargin}>
<FormattedMessage id="ui-data-import.logViewer.orderLine" />
</Headline>
),
logs: poLinesData,
error: getErrorMessage(OPTIONS.ORDER),
errorBlockId: 'order-line-error',
}, {
label: (
<Headline margin="none" className={sharedCss.leftMargin}>
<FormattedMessage id="ui-data-import.logViewer.order" />
</Headline>
),
logs: orderData,
}],
[OPTIONS.INVOICE]: [{
label: (
<Headline margin="none" className={sharedCss.leftMargin}>
<FormattedMessage id="ui-data-import.logViewer.invoiceLine" />
</Headline>
),
logs: invoiceLineData,
error: getErrorMessage(OPTIONS.INVOICE).invoiceLineInfo,
errorBlockId: 'invoice-line-error',
}, {
label: (
<Headline margin="none" className={sharedCss.leftMargin}>
<FormattedMessage id="ui-data-import.logViewer.invoice" />
</Headline>
),
logs: invoicesData,
error: getErrorMessage(OPTIONS.INVOICE).invoiceInfo,
errorBlockId: 'invoice-error',
}],
[OPTIONS.SRS_MARC_BIB]: srsMarcBibLogs,
[OPTIONS.INSTANCE]: instanceLogs,
[OPTIONS.HOLDINGS]: holdingsLogs,
[OPTIONS.ITEM]: itemsLogs,
[OPTIONS.AUTHORITY]: authorityLogs,
[OPTIONS.ORDER]: orderLogs,
[OPTIONS.INVOICE]: invoiceLogs,
};

return (
Expand Down
Loading
Loading