Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions ui-rs/src/components/Flow/FlowViewComponents/Citation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { FormattedMessage } from 'react-intl';
import { Accordion, Col, KeyValue, Row } from '@folio/stripes/components';

const Citation = ({ request }) => {
if (request.serviceType?.value !== 'Copy') return null;
const { bibliographicInfo = {}, publicationInfo = {}, serviceInfo = {} } = request?.illRequest ?? {};
if (serviceInfo.serviceType !== 'Copy') return null;

const { titleOfComponent, authorOfComponent, volume, issue, pagesRequested } = bibliographicInfo;
// Compliance codes are open codes a partner may send in any casing; the keys
// are lower case, and an unrecognised code shows as itself.
const copyright = serviceInfo.copyrightCompliance?.['#text'];

return (
<Accordion
Expand All @@ -14,48 +20,48 @@ const Citation = ({ request }) => {
<Col xs={6}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.titleOfComponent" />}
value={request.titleOfComponent}
value={titleOfComponent}
/>
</Col>
<Col xs={3}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.volume" />}
value={request.volume}
value={volume}
/>
</Col>
<Col xs={3}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.date" />}
value={request.publicationDate}
value={publicationInfo.publicationDate}
/>
</Col>
</Row>
<Row>
<Col xs={6}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.authorOfComponent" />}
value={request.authorOfComponent}
value={authorOfComponent}
/>
</Col>
<Col xs={3}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.issue" />}
value={request.issue}
value={issue}
/>
</Col>
<Col xs={3}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.pages" />}
value={request.pagesRequested}
value={pagesRequested}
/>
</Col>
</Row>
{request.copyrightType?.value !== undefined &&
{copyright &&
<Row>
<Col xs={6}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.copyrightType" />}
value={<FormattedMessage id={`ui-rs.refdata.copyrightType.${request.copyrightType?.value}`} />}
value={<FormattedMessage id={`ui-rs.refdata.copyrightType.${copyright.toLowerCase()}`} defaultMessage={copyright} />}
/>
</Col>
</Row>
Expand Down
48 changes: 42 additions & 6 deletions ui-rs/src/components/Flow/FlowViewComponents/RequestInfo.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React, { useState } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { FormattedMessage, useIntl } from 'react-intl';
import { Accordion, Col, Headline, KeyValue, Layout, NoValue, Row } from '@folio/stripes/components';
import { Accordion, Col, FormattedUTCDate, Headline, KeyValue, Layout, NoValue, Row } from '@folio/stripes/components';

import formatCosts from '../../../util/formatCosts';
import { findAgreedCost, formatConditionCost } from '../../../util/formatCondition';
import { useNotificationList } from '../../chat/useNotifications';

const RequestInfo = ({ request }) => {
const intl = useIntl();
Expand All @@ -13,13 +17,24 @@ const RequestInfo = ({ request }) => {
return (
<Col xs={3}>
<KeyValue
label={<FormattedMessage id={`ui-rs.flow.info.${labelId}`} />}
label={<FormattedMessage id={labelId} />}
value={value}
/>
</Col>
);
};

const { serviceType } = serviceInfo;
const serviceLevel = serviceInfo.serviceLevel?.['#text'];
const maximumCost = formatCosts(illRequest.billingInfo?.maximumCosts);

// Shares its query key with the chat badge ViewRoute already fetches.
const { data: notifications } = useNotificationList(request?.id);
const agreedCost = findAgreedCost(notifications?.items, request?.supplierSymbol);

// The supplier's side of the exchange, as the last ISO 18626 response.
const { statusInfo, deliveryInfo } = request?.illResponse ?? {};

const location = useLocation();
const [showStateCode, setShowStateCode] = useState(false);

Expand All @@ -33,7 +48,7 @@ const RequestInfo = ({ request }) => {
<FormattedMessage id={`stripes-reshare.states.${request.state}`} defaultMessage={request.state} />
{showStateCode && <span> ({request.state})</span>}
</Headline>
{`${intl.formatMessage({ id: 'ui-rs.flow.info.updated' }, { date: intl.formatDate(request.timestamp) })} `}
{`${intl.formatMessage({ id: 'ui-rs.flow.info.updated' }, { date: intl.formatDate(request.updatedAt) })} `}
<Link to={{
pathname: location?.pathname?.replace('flow', 'details'),
search: location?.search,
Expand All @@ -47,9 +62,30 @@ const RequestInfo = ({ request }) => {
</Layout>
<Layout className="padding-top-gutter">
<Row>
{colKeyVal('requester', request.requesterSymbol || <NoValue />)}
{colKeyVal('supplier', request.supplierSymbol || <NoValue />)}
{colKeyVal('volumesNeeded', bibliographicInfo.volume || <NoValue />)}
{colKeyVal('ui-rs.flow.info.requester', request.requesterSymbol || <NoValue />)}
{colKeyVal('ui-rs.flow.info.supplier', request.supplierSymbol || <NoValue />)}
{colKeyVal('ui-rs.flow.info.volumesNeeded', bibliographicInfo.volume || <NoValue />)}
{colKeyVal(
'ui-rs.information.serviceType',
serviceType
? <FormattedMessage id={`ui-rs.information.serviceType.${serviceType}`} defaultMessage={serviceType} />
: <NoValue />
)}
</Row>
<Row>
{serviceLevel !== undefined && colKeyVal(
'ui-rs.information.serviceLevel',
<FormattedMessage id={`ui-rs.refdata.serviceLevel.${serviceLevel}`} defaultMessage={serviceLevel} />
)}
{maximumCost !== undefined && colKeyVal('ui-rs.information.maximumCost', maximumCost)}
{agreedCost !== undefined && colKeyVal('ui-rs.information.cost', formatConditionCost(agreedCost))}
</Row>
<Row>
{colKeyVal(
'ui-rs.flow.info.dueDate',
statusInfo?.dueDate ? <FormattedUTCDate value={statusInfo.dueDate} /> : <NoValue />
)}
{colKeyVal('ui-rs.flow.info.itemBarcode', deliveryInfo?.itemId || <NoValue />)}
</Row>
<Row>
{serviceInfo.note &&
Expand Down
59 changes: 42 additions & 17 deletions ui-rs/src/components/Flow/FlowViewComponents/RequestingUser.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,74 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Link, useLocation } from 'react-router-dom';
import { FormattedMessage } from 'react-intl';
import { Accordion, Col, KeyValue, Row } from '@folio/stripes/components';
import { useStripes } from '@folio/stripes/core';
import { upNLevels } from '@projectreshare/stripes-reshare';

import patronEmail from '../../../util/patronEmail';

const RequestingUser = ({ request }) => {
const stripes = useStripes();
const patronURL = stripes?.config?.reshare?.patronURL?.replace('{patronid}', request.patronIdentifier);
const location = useLocation();
const patronInfo = request?.illRequest?.patronInfo ?? {};
const { patronId, surname, givenName } = patronInfo;
const email = patronEmail(patronInfo);

if (request?.side !== 'borrowing') return null;
if (!patronId && !surname && !givenName) return null;

Comment thread
skomorokh marked this conversation as resolved.
if (!request.isRequester || !patronURL) return null;
// Without a configured patron URL there is no local ILS to cross-reference, and
// this section is deliberately absent rather than showing patron detail alone.
const patronURLTemplate = stripes?.config?.reshare?.patronURL;
if (!patronURLTemplate) return null;

const patronURL = patronId ? patronURLTemplate.replace('{patronid}', patronId) : null;
const listPath = upNLevels(location, 2).split('?')[0];

return (
<Accordion
id="requestingUser"
label={<FormattedMessage id="ui-rs.flow.sections.requestingUser" />}
>
<Row>
<Col xs={4}>
<Col xs={3}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.lastName" />}
value={request.patronSurname}
value={surname}
/>
</Col>
<Col xs={4}>
<Col xs={3}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.firstName" />}
value={request.patronGivenName}
value={givenName}
/>
</Col>
<Col xs={4}>
<Col xs={3}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.userId" />}
value={request.patronIdentifier}
value={patronId}
/>
</Col>
<Col xs={3}>
<KeyValue
label={<FormattedMessage id="ui-rs.information.emailAddress" />}
value={email}
/>
</Col>
</Row>
<Row>
<Col xs={4}>
<Link to={patronURL}><FormattedMessage id="ui-rs.flow.info.patronLink" /></Link>
</Col>
<Col xs={4}>
<Link to={`/request/requests?filters=terminal.false&qindex=patronIdentifier&query=${request.patronIdentifier}&sort=-dateCreated`}>
<FormattedMessage id="ui-rs.flow.info.patronQuery" />
</Link>
</Col>
{patronURL &&
<Col xs={4}>
<Link to={patronURL}><FormattedMessage id="ui-rs.flow.info.patronLink" /></Link>
</Col>
}
{patronId &&
<Col xs={4}>
<Link to={`${listPath}?filters=terminal.false&qindex=patron&query=${encodeURIComponent(patronId)}&sort=-dateCreated`}>
<FormattedMessage id="ui-rs.flow.info.patronQuery" />
</Link>
</Col>
}
</Row>
</Accordion>
);
Expand Down
4 changes: 3 additions & 1 deletion ui-rs/src/components/Flow/FlowViewComponents/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import TitleAndSILink from './TitleAndSILink';
import RequestInfo from './RequestInfo';
import Citation from './Citation';
import RequestingUser from './RequestingUser';
import ActionAccordion from './ActionAccordion';
import LoanConditions from './LoanConditions';

export default [TitleAndSILink, RequestInfo, LoanConditions, ActionAccordion];
export default [TitleAndSILink, RequestInfo, RequestingUser, Citation, LoanConditions, ActionAccordion];
23 changes: 2 additions & 21 deletions ui-rs/src/components/PatronRequestForm/formMapping.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import { CREATE, EDIT } from './operations';

const ID_ARRAYS = {
bibliographicItemId: {
idKey: 'bibliographicItemIdentifier',
codeKey: 'bibliographicItemIdentifierCode',
codes: ['ISBN', 'ISSN'],
},
bibliographicRecordId: {
idKey: 'bibliographicRecordIdentifier',
codeKey: 'bibliographicRecordIdentifierCode',
codes: ['OCLC'],
},
};
import { ID_ARRAYS, extractIdentifiers } from '../../util/bibIdentifiers';

// Entries for the codes the form exposes, with any other code left as it was, so
// identifiers we do not display survive a PUT.
Expand All @@ -29,14 +17,7 @@ const brokerToForm = (request) => {
const illRequest = request?.illRequest ?? {};
const { supplierUniqueRecordId, ...bibliographicInfo } = illRequest.bibliographicInfo ?? {};

const identifiers = {};
Object.entries(ID_ARRAYS).forEach(([arrayKey, { idKey, codeKey, codes }]) => {
codes.forEach(code => {
const value = (bibliographicInfo[arrayKey] ?? [])
.find(e => e?.[codeKey]?.['#text'] === code)?.[idKey];
if (value) identifiers[code] = value;
});
});
const identifiers = extractIdentifiers(bibliographicInfo);

return {
...illRequest,
Expand Down
Loading
Loading