Skip to content

Commit

Permalink
Add useGetWorkUrlFromIdentifier to support material linking from loans
Browse files Browse the repository at this point in the history
Since all data from loans comes from Publizon, we don’t have a `workId`, which is required to link to the material. Therefore, I use the `useComplexSearchWithPaginationQuery` to find the work using the ISBN (identifier) and construct the `workId` into a URL, e.g., `/work/work-of:870970-basis:62986115`.  Additionally, if it finds the material type, it adds that as a parameter.
  • Loading branch information
kasperbirch1 committed Dec 2, 2024
1 parent 016b064 commit a23e109
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 26 deletions.
26 changes: 8 additions & 18 deletions src/apps/loan-list/modal/material-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { FC, useState } from "react";
import ReservationIcon from "@danskernesdigitalebibliotek/dpl-design-system/build/icons/collection/Reservations.svg";
import LoansIcon from "@danskernesdigitalebibliotek/dpl-design-system/build/icons/collection/Loans.svg";
import EbookIcon from "@danskernesdigitalebibliotek/dpl-design-system/build/icons/collection/Ebook.svg";
import ExternalLinkIcon from "@danskernesdigitalebibliotek/dpl-design-system/build/icons/buttons/icon-btn-external-link.svg";
import { useText } from "../../../core/utils/text";
import { isDigital } from "../utils/helpers";
import { materialIsOverdue } from "../../../core/utils/helpers/general";
Expand All @@ -22,6 +21,7 @@ import { RequestStatus } from "../../../core/utils/types/request";
import { RenewedLoanV2 } from "../../../core/fbs/model";
import RenewalModalMessage from "../../../components/renewal/RenewalModalMessage";
import { formatDate } from "../../../core/utils/helpers/date";
import useGetWorkUrlFromIdentifier from "../../../core/utils/useGetWorkUrlFromIdentifier";

interface MaterialDetailsProps {
loan: LoanType | null;
Expand All @@ -33,14 +33,14 @@ const MaterialDetails: FC<MaterialDetailsProps & MaterialProps> = ({
material,
modalId
}) => {
const { workUrl } = useGetWorkUrlFromIdentifier(loan?.identifier);
const [renewingStatus, setRenewingStatus] = useState<RequestStatus>("idle");
const [renewingResponse, setRenewingResponse] = useState<
RenewedLoanV2[] | null
>(null);

const t = useText();
const u = useUrls();
const ereolenMyPageUrl = u("ereolenMyPageUrl");
const viewFeesAndCompensationRatesUrl = u("viewFeesAndCompensationRatesUrl");

if (!loan) {
Expand Down Expand Up @@ -119,18 +119,13 @@ const MaterialDetails: FC<MaterialDetailsProps & MaterialProps> = ({
renewalStatusList={renewalStatusList}
/>
)}
{isDigital(loan) && (
{isDigital(loan) && workUrl && (
<div className="modal-details__buttons modal-details__buttons--hide-on-mobile">
<Link
href={ereolenMyPageUrl}
href={workUrl}
className="btn-primary btn-filled btn-small arrow__hover--right-small"
>
{t("materialDetailsGoToEreolenText")}
<img
src={ExternalLinkIcon}
className="btn-icon invert"
alt=""
/>
{t("materialDetailsGoToMaterialText")}
</Link>
</div>
)}
Expand Down Expand Up @@ -186,18 +181,13 @@ const MaterialDetails: FC<MaterialDetailsProps & MaterialProps> = ({
renewalStatusList={renewalStatusList}
/>
)}
{isDigital(loan) && (
{isDigital(loan) && workUrl && (
<div className="modal-details__buttons">
<Link
href={ereolenMyPageUrl}
href={workUrl}
className="btn-primary btn-filled btn-small arrow__hover--right-small modal-details__buttons__full-width"
>
{t("materialDetailsGoToEreolenText")}
<img
src={ExternalLinkIcon}
className="btn-icon invert"
alt=""
/>
{t("materialDetailsGoToMaterialText")}
</Link>
</div>
)}
Expand Down
16 changes: 8 additions & 8 deletions src/core/storybook/materialDetailsModalArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ export const argTypes = {
defaultValue: { summary: "Expired" }
}
},
materialDetailsGoToEreolenText: {
materialDetailsGoToMaterialText: {
table: {
type: { summary: "text" },
defaultValue: { summary: "Go to eReolen" }
defaultValue: { summary: "Go to material" }
},
control: { type: "text" }
},
Expand Down Expand Up @@ -77,10 +77,10 @@ export const argTypes = {
},
control: { type: "text" }
},
ereolenMyPageUrl: {
materialUrl: {
table: {
type: { summary: "text" },
defaultValue: { summary: "https://unsplash.com/photos/wd6YQy0PJt8" } // open source image of a red panda
defaultValue: { summary: "work/:workid" }
},
control: { type: "text" }
}
Expand All @@ -94,12 +94,12 @@ export default {
materialDetailsMaterialNumberLabelText: "Material Item Number",
materialDetailsLinkToPageWithFeesText: "Read more about fees",
materialDetailsOverdueText: "Expired",
materialDetailsGoToEreolenText: "Go to eReolen",
materialDetailsGoToMaterialText: "Go to material",
materialDetailsDigitalDueDateLabelText: "Expires",
materialDetailsRenewLoanButtonText: "Renew your loan",
feesPageUrl: "/user/me/fees",
viewFeesAndCompensationRatesUrl: "https://unsplash.com/photos/wd6YQy0PJt8", // open source image of a red panda
ereolenMyPageUrl: "https://unsplash.com/photos/wd6YQy0PJt8" // open source image of a red panda
materialUrl: "work/:workid"
};

export interface MaterialDetailsModalProps {
Expand All @@ -110,8 +110,8 @@ export interface MaterialDetailsModalProps {
materialDetailsLinkToPageWithFeesText: string;
materialDetailsOverdueText: string;
feesPageUrl: string;
ereolenMyPageUrl: string;
materialDetailsGoToEreolenText: string;
materialUrl: string;
materialDetailsGoToMaterialText: string;
materialDetailsDigitalDueDateLabelText: string;
materialDetailsRenewLoanButtonText: string;
}
58 changes: 58 additions & 0 deletions src/core/utils/useGetWorkUrlFromIdentifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useMemo } from "react";
import { useComplexSearchWithPaginationQuery } from "../dbc-gateway/generated/graphql";
import { useUrls } from "./url";
import { constructMaterialUrl } from "./helpers/url";
import { WorkId } from "./types/ids";
import { getMaterialTypes } from "./helpers/general";
import { Manifestation } from "./types/entities";

type UseGetWorkUrlFromIdentifierResult = {
workUrl: URL | null;
isLoading: boolean;
isError: boolean;
};

const useGetWorkUrlFromIdentifier = (
identifier: string | undefined | null
): UseGetWorkUrlFromIdentifierResult => {
const u = useUrls();
const materialUrl = u("materialUrl");

const { data, isLoading, isError } = useComplexSearchWithPaginationQuery(
{
cql: `term.isbn=${identifier}`,
offset: 0,
limit: 1,
filters: {}
},
{
enabled: Boolean(identifier)
}
);

const workUrl = useMemo(() => {
if (!data || !identifier) return null;

const work = data.complexSearch?.works?.[0];
if (!work) return null;

const workId = work.workId as WorkId;
const manifestationWithSameIdentifier = work.manifestations?.all?.find(
(manifestation) =>
manifestation.identifiers?.some((id) => id.value === identifier)
);
const materialType = manifestationWithSameIdentifier
? getMaterialTypes([manifestationWithSameIdentifier] as Manifestation[])
: undefined;

return constructMaterialUrl(
materialUrl,
workId,
materialType ? String(materialType) : undefined
);
}, [data, identifier, materialUrl]);

return { workUrl, isLoading, isError };
};

export default useGetWorkUrlFromIdentifier;

0 comments on commit a23e109

Please sign in to comment.