Skip to content

Commit

Permalink
Get manifestation data by best representation for parallel reservations
Browse files Browse the repository at this point in the history
Use our new query to retrieve data from the best representation of the
owner work of one of the faust ids in our parallel reservation.

In general our parallel reservation data structure only contain a single
faust id (from the first reservation in the group). This may seem liked
a problem but based on the assumption that any faust id in the group 
should return the same owner work which should return the same best 
representation this should actually be OK.

Since parallel reservations may appear in different locations throughout
the app handling is added to the fetchMaterial() higher order component.

We can the utilize the fact that both hooks for retrieving material data
use the same fragment.

Expand the reservation list Cypress test to show that data fetching for
parallel reservations works.
  • Loading branch information
kasperg committed Nov 16, 2023
1 parent 8e88047 commit 8e20ab9
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 12 deletions.
50 changes: 50 additions & 0 deletions cypress/fixtures/reservation-list/work-bestrepresentation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"data": {
"manifestation": {
"ownerWork": {
"manifestations": {
"bestRepresentation": {
"pid": "870970-basis:22629344",
"titles": {
"full": [
"Best representation of dummy title"
]
},
"abstract": [
"Dummy Some abstract ..."
],
"edition": {
"summary": "3. udgave, 1. oplag (2019)",
"publicationYear": {
"display": "2006"
}
},
"materialTypes": [
{
"specific": "Dummy bog"
}
],
"series": [
{
"numberInSeries": {
"number": [
1
]
},
"title": "Detektivbureau Nr. 2"
}
],
"creators": [
{
"display": "Dummy Jens Jensen"
},
{
"display": "Dummy Some Corporation"
}
]
}
}
}
}
}
}
34 changes: 25 additions & 9 deletions src/apps/loan-list/materials/utils/material-fetch-hoc.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import React, { useEffect, useState, ComponentType, FC } from "react";
import { useGetManifestationViaMaterialByFaustQuery } from "../../../../core/dbc-gateway/generated/graphql";
import {
ManifestationBasicDetailsFragment,
useGetManifestationViaBestRepresentationByFaustQuery,
useGetManifestationViaMaterialByFaustQuery
} from "../../../../core/dbc-gateway/generated/graphql";
import { Product } from "../../../../core/publizon/model";
import { BasicDetailsType } from "../../../../core/utils/types/basic-details-type";
import { mapManifestationToBasicDetailsType } from "../../../../core/utils/helpers/list-mapper";
Expand Down Expand Up @@ -35,21 +39,33 @@ const fetchMaterial =
if (item?.faust) {
const [material, setMaterial] = useState<BasicDetailsType>();

const { isSuccess: isSuccessManifestation, data } =
useGetManifestationViaMaterialByFaustQuery({
let manifestation: ManifestationBasicDetailsFragment | null = null;
if (item.reservationIds && item.reservationIds.length > 1) {
const { isSuccess, data } =
useGetManifestationViaBestRepresentationByFaustQuery({
faust: item.faust
});
if (isSuccess && data?.manifestation) {
manifestation =
data.manifestation.ownerWork.manifestations.bestRepresentation;
}
} else {
const { isSuccess, data } = useGetManifestationViaMaterialByFaustQuery({
faust: item.faust
});
if (isSuccess && data?.manifestation) {
manifestation = data.manifestation;
}
}

useEffect(() => {
if (data && isSuccessManifestation && data.manifestation) {
setMaterial(mapManifestationToBasicDetailsType(data));
} else {
// todo error handling, missing in figma
if (manifestation) {
setMaterial(mapManifestationToBasicDetailsType(manifestation));
}
}, [isSuccessManifestation, data]);
}, [manifestation]);

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

// if the fallback component is provided we can show it while the data is loading
if (!material) return FallbackComponent ? <FallbackComponent /> : null;
Expand Down
83 changes: 83 additions & 0 deletions src/apps/reservation-list/list/reservation-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,89 @@ describe("Reservation list", () => {
.should("exist")
.should("have.text", "At the moment you have 0 reservations");
});

it("Reservations list shows parallel reservation", () => {
cy.intercept(
"GET",
"**/external/v1/agencyid/patrons/patronid/reservations/v2**",
{
statusCode: 200,
body: [
{
reservationId: 67804976,
recordId: "46985591",
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: null,
// We have two reservations with the same transactionId which makes
// it a parallel reservation.
transactionId: "c6742151-f4a7-4655-a94f-7bd6a0009431",
reservationType: "parallel"
},
{
reservationId: 67804977,
recordId: "46985592",
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: null,
transactionId: "c6742151-f4a7-4655-a94f-7bd6a0009431",
reservationType: "parallel"
}
]
}
).as("physical_reservations");

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

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

cy.interceptRest({
aliasName: "work-bestrepresentation",
httpMethod: "POST",
url: "**/next/**",
fixtureFilePath: "reservation-list/work-bestrepresentation.json"
});

cy.getBySel("list-reservation-container")
.find(".list-reservation")
// Even though we return multiple reservations they are parallel and
// should be represented as one.
.should("have.length", 1)
.get(".list-reservation__header")
// The title should be the one returned by the best representation
// fixture.
.should("contain", "Best representation of dummy title")
// 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 best representation title.
.should("contain", "Best representation of dummy title");
});
});

export default {};
9 changes: 6 additions & 3 deletions src/core/utils/helpers/list-mapper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { head, keys, values } from "lodash";
import { LoanV2, ReservationDetailsV2 } from "../../fbs/model";
import { FaustId } from "../types/ids";
import { GetManifestationViaMaterialByFaustQuery } from "../../dbc-gateway/generated/graphql";
import {
GetManifestationViaMaterialByFaustQuery,

Check warning on line 5 in src/core/utils/helpers/list-mapper.ts

View workflow job for this annotation

GitHub Actions / Lint .js and .jsx

'GetManifestationViaMaterialByFaustQuery' is defined but never used
ManifestationBasicDetailsFragment
} from "../../dbc-gateway/generated/graphql";
import { BasicDetailsType } from "../types/basic-details-type";
import { Product, Loan, Reservation } from "../../publizon/model";
import { LoanType } from "../types/loan-type";
Expand Down Expand Up @@ -122,7 +125,7 @@ export const mapProductToBasicDetailsType = (material: Product) => {
// so digital/physical loans/reservations can use the same components,
// as their UI is often quite similar
export const mapManifestationToBasicDetailsType = (
material: GetManifestationViaMaterialByFaustQuery
material: ManifestationBasicDetailsFragment
) => {
const {
edition,
Expand All @@ -133,7 +136,7 @@ export const mapManifestationToBasicDetailsType = (
creators,
series,
languages
} = material?.manifestation || {};
} = material;
const isoCode = languages?.main?.[0]?.isoCode ?? "";
const description = abstract ? abstract[0] : "";
const {
Expand Down

0 comments on commit 8e20ab9

Please sign in to comment.