Skip to content

Commit

Permalink
Merge pull request #1322 from danskernesdigitalebibliotek/ill-reserva…
Browse files Browse the repository at this point in the history
…tions

Use FBS record for interlibrary loans and reservations where material cannot be found in FBI
  • Loading branch information
kasperg authored Jul 10, 2024
2 parents 3d59582 + c87a783 commit bd0b706
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 16 deletions.
78 changes: 78 additions & 0 deletions src/apps/loan-list/list/loan-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,84 @@ describe("Loan list", () => {
);
});

it("It shows interlibrary record when work is not found", () => {
cy.intercept("GET", "**/external/agencyid/patrons/patronid/loans/v2**", {
statusCode: 200,
body: [
{
isRenewable: true,
isLongtermLoan: false,
loanDetails: {
loanId: 956250509,
materialItemNumber: "3846990827",
recordId: "28843238",
periodical: null,
loanDate: "2022-10-14T16:43:25.325",
dueDate: "2022-10-28",
loanType: "loan",
ilBibliographicRecord: {
author: "Thorpe, D.R.",
bibliographicCategory: "mono",
edition: null,
isbn: "9781844135417",
issn: null,
language: "eng",
mediumType: "a xx",
periodicalNumber: null,
periodicalVolume: null,
placeOfPublication: "London",
publicationDate: "2011",
publicationDateOfComponent: null,
publisher: "Pimlico",
recordId: "2449448",
title: "Supermac : the life of Harold Macmillan"
},
materialGroup: {
name: "fon2",
description: "Flere CD-plader"
}
}
}
]
}).as("physical_loans");

cy.intercept("GET", "**/v1/user/**", {
statusCode: 200,
body: {
reservations: [],
code: 101,
message: "OK"
}
}).as("digital_loans");

// No works are found. This should make the reservation use data from the
// ilBibliographicRecord property.
cy.intercept("POST", "**/next*/**", {
statusCode: 200,
body: {
data: {}
}
}).as("work_not_found");

cy.visit("/iframe.html?path=/story/apps-loan-list--loan-list-entry");

cy.get(".list-reservation-container")
.find(".list-reservation")
.get(".list-reservation__header")
// The title should be the one returned by ilBibliographicRecord property
// on the reservation.
.should("contain", "Supermac : the life of Harold Macmillan")
// Open the modal to see the details.
.click();

cy.getBySel("modal")
// Modal should be open.
.should("exist")
.find(".modal-details__title")
// Details should also contain the ilBibliographicRecord title.
.should("contain", "Supermac : the life of Harold Macmillan");
});

it("Empty digital loan list", () => {
cy.intercept("GET", "**/v1/user/**", {
statusCode: 200,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,13 @@ const SelectableMaterial: FC<SelectableMaterialProps & MaterialProps> = ({
role="button"
tabIndex={0}
>
<div className="list-materials__content-status">
<div className="status-label status-label--outline ">
{materialType}
{materialType && (
<div className="list-materials__content-status">
<div className="status-label status-label--outline ">
{materialType}
</div>
</div>
</div>
)}
{statusBadgeComponentMobile || null}
<p className="list-materials__content__header mt-8" lang={lang || ""}>
{title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,16 @@ const MaterialInfo: FC<MaterialInfoProps> = ({
/>
</div>
<div className="list-reservation__information">
{materialType && (
<div>
<div className="status-label status-label--outline">
{materialType}
{/* Add a div for material types even if there are none to ensure element alignment */}
<div>
{materialType && (
<div>
<div className="status-label status-label--outline">
{materialType}
</div>
</div>
</div>
)}
)}
</div>
<div className="list-reservation__about">
<button
onClick={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
Expand Down
6 changes: 4 additions & 2 deletions src/apps/loan-list/materials/utils/material-fetch-hoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,18 @@ const fetchMaterial =
useEffect(() => {
if (manifestation) {
setMaterial(mapManifestationToBasicDetailsType(manifestation));
} else if (item.details) {
setMaterial(item.details);
}
}, [manifestation]);
}, [manifestation, item.details]);

// if the fallback component is provided we can show it while the data is loading
if (isLoadingAnything) {
return FallbackComponent ? <FallbackComponent /> : null;
}

// in cases where the material is not found we return null, else we would load forever
if (!manifestation) return null;
if (!material) return null;

return (
<Component
Expand Down
81 changes: 81 additions & 0 deletions src/apps/reservation-list/list/reservation-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,87 @@ describe("Reservation list", () => {
// Details should also contain the best representation title.
.should("contain", "Best representation of dummy title");
});

it("Reservations list falls back on interlibrary record when work is not found", () => {
cy.intercept(
"GET",
"**/external/v1/agencyid/patrons/patronid/reservations/v2**",
{
statusCode: 200,
body: [
{
reservationId: 67804976,
recordId: "2449448",
state: "reserved",
pickupBranch: "DK-775100",
pickupDeadline: null,
expiryDate: "2022-09-21",
dateOfReservation: "2022-06-14T09:00:50.059",
numberInQueue: 1,
periodical: null,
pickupNumber: null,
ilBibliographicRecord: {
author: "Thorpe, D.R.",
bibliographicCategory: "mono",
edition: null,
isbn: "9781844135417",
issn: null,
language: "eng",
mediumType: "a xx",
periodicalNumber: null,
periodicalVolume: null,
placeOfPublication: "London",
publicationDate: "2011",
publicationDateOfComponent: null,
publisher: "Pimlico",
recordId: "2449448",
title: "Supermac : the life of Harold Macmillan"
},
transactionId: "c6742151-f4a7-4655-a94f-7bd6a0009431",
reservationType: "normal"
}
]
}
).as("physical_reservations");

cy.intercept("GET", "**/v1/user/**", {
statusCode: 200,
body: {
reservations: [],
code: 101,
message: "OK"
}
}).as("digital_reservations");

// No works are found. This should make the reservation use data from the
// ilBibliographicRecord property.
cy.intercept("POST", "**/next*/**", {
statusCode: 200,
body: {
data: {}
}
}).as("work_not_found");

cy.visit(
"/iframe.html?path=/story/apps-reservation-list--reservation-list-entry"
);

cy.getBySel("list-reservation-container")
.find(".list-reservation")
.get(".list-reservation__header")
// The title should be the one returned by ilBibliographicRecord property
// on the reservation.
.should("contain", "Supermac : the life of Harold Macmillan")
// Open the modal to see the details.
.click();

cy.getBySel("modal")
// Modal should be open.
.should("exist")
.find(".modal-details__title")
// Details should also contain the ilBibliographicRecord title.
.should("contain", "Supermac : the life of Harold Macmillan");
});
});

export default {};
27 changes: 24 additions & 3 deletions src/core/utils/helpers/list-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,17 @@ export const mapFBSLoanToLoanType = (list: LoanV2[]): LoanType[] => {
loanType: loanDetails.loanType,
identifier: null,
faust: (loanDetails.recordId as FaustId) || null,
loanId: loanDetails.loanId
loanId: loanDetails.loanId,
details: loanDetails.ilBibliographicRecord
? {
title: loanDetails.ilBibliographicRecord.title,
authors: loanDetails.ilBibliographicRecord.author,
authorsShort: loanDetails.ilBibliographicRecord.author,
firstAuthor: loanDetails.ilBibliographicRecord.author,
year: loanDetails.ilBibliographicRecord.publicationDate,
lang: loanDetails.ilBibliographicRecord.language
}
: null
};
});
};
Expand Down Expand Up @@ -251,7 +261,8 @@ export const mapFBSReservationGroupToReservationType = (
pickupDeadline,
pickupNumber,
periodical,
records
records,
ilBibliographicRecord
}) => {
return {
periodical: periodical?.displayText || "",
Expand All @@ -263,7 +274,17 @@ export const mapFBSReservationGroupToReservationType = (
pickupBranch,
pickupDeadline,
pickupNumber,
reservationIds: values(records)
reservationIds: values(records),
details: ilBibliographicRecord
? {
title: ilBibliographicRecord.title,
authors: ilBibliographicRecord.author,
authorsShort: ilBibliographicRecord.author,
firstAuthor: ilBibliographicRecord.author,
year: ilBibliographicRecord.publicationDate,
lang: ilBibliographicRecord.language
}
: null
};
}
);
Expand Down
9 changes: 8 additions & 1 deletion src/core/utils/types/list-type.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FaustId, LoanId } from "./ids";
import { Nullable } from "./nullable";
import { BasicDetailsType } from "./basic-details-type";

export type ListIdsType = {
faust: FaustId;
Expand All @@ -8,7 +9,13 @@ export type ListIdsType = {
loanId: LoanId | null;
};

export type ListType = Nullable<Partial<ListIdsType>>;
export type ListType = Nullable<
Partial<
ListIdsType & {
details: BasicDetailsType;
}
>
>;

export function listId(listItem: ListType): string {
if (listItem?.reservationIds && listItem.reservationIds.length > 0) {
Expand Down

0 comments on commit bd0b706

Please sign in to comment.