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

WIP: DDFBRA-251 - User can open their loaned e materials #1573

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
2 changes: 2 additions & 0 deletions src/apps/loan-list/modal/material-details-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Todo: Fix infinite loop in MaterialDetailsModal
import React, { FC, ReactNode } from "react";
import Modal from "../../../core/utils/modal";
import { useText } from "../../../core/utils/text";
Expand Down Expand Up @@ -33,6 +34,7 @@ const MaterialDetailsModal: FC<MaterialDetailsModalProps> = ({
children
}) => {
const t = useText();
// console.log("Rendering MaterialDetailsModal:");

if (!modalId) {
return null;
Expand Down
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
2 changes: 2 additions & 0 deletions src/apps/material/material.entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ interface MaterialEntryTextProps {
okButtonText: string;
onlineLimitMonthAudiobookInfoText: string;
onlineLimitMonthEbookInfoText: string;
onlineMaterialPlayerText: string;
onlineMaterialReaderText: string;
onlineMaterialTeaserText: string;
openOrderAuthenticationErrorText: string;
openOrderErrorMissingPincodeText: string;
Expand Down
10 changes: 10 additions & 0 deletions src/apps/material/material.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,14 @@ const meta: Meta<typeof MaterialEntry> = {
description: "Online limit info text",
control: { type: "text" }
},
onlineMaterialPlayerText: {
description: "Material button online player text",
control: { type: "text" }
},
onlineMaterialReaderText: {
description: "Material button online reader text",
control: { type: "text" }
},
onlineMaterialTeaserText: {
description: "Material button online teaser text",
control: { type: "text" }
Expand Down Expand Up @@ -795,6 +803,8 @@ const meta: Meta<typeof MaterialEntry> = {
"You have borrowed @count out of @limit possible e-books this month",
onlineLimitMonthAudiobookInfoText:
"You have borrowed @count out of @limit possible audio-books this month",
onlineMaterialPlayerText: "Listen to @materialType",
onlineMaterialReaderText: "Read @materialType",
onlineMaterialTeaserText: "Try @materialType",
approveReservationText: "Approve reservation",
shiftText: "Change",
Expand Down
18 changes: 11 additions & 7 deletions src/apps/material/material.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,13 @@ import {
getBestMaterialTypeForWork,
getDetailsListData,
getInfomediaIds,
getManifestationIsbn,
getManifestationsOrderByTypeAndYear,
isParallelReservation
} from "./helper";
import MaterialDisclosure from "./MaterialDisclosure";
import ReservationFindOnShelfModals from "./ReservationFindOnShelfModals";
import PlayerModal from "../../components/material/player-modal/PlayerModal";
import { hasPlayerManifestation } from "../../components/reader-player/helper";
import useReaderPlayer from "../../core/utils/useReaderPlayer";

export interface MaterialProps {
wid: WorkId;
Expand All @@ -57,6 +56,11 @@ const Material: React.FC<MaterialProps> = ({ wid }) => {
const { data: userData } = usePatronData();
const [isUserBlocked, setIsUserBlocked] = useState<boolean | null>(null);
const { track } = useStatistics();
const {
type: readerPlayerType,
identifier,
orderId
} = useReaderPlayer(selectedManifestations);

useEffect(() => {
setIsUserBlocked(!!(userData?.patron && isBlocked(userData.patron)));
Expand Down Expand Up @@ -173,7 +177,6 @@ const Material: React.FC<MaterialProps> = ({ wid }) => {
setSelectedPeriodical={setSelectedPeriodical}
/>
))}

{infomediaIds.length > 0 && !isAnonymous() && !isUserBlocked && (
<InfomediaModal
selectedManifestations={selectedManifestations}
Expand All @@ -196,10 +199,11 @@ const Material: React.FC<MaterialProps> = ({ wid }) => {
setSelectedPeriodical={setSelectedPeriodical}
/>
)}
{hasPlayerManifestation(selectedManifestations) && (
<PlayerModal
identifier={getManifestationIsbn(selectedManifestations[0])}
/>
{readerPlayerType === "player" && (
<>
{identifier && <PlayerModal identifier={identifier} />}
{orderId && <PlayerModal orderId={orderId} />}
</>
)}
</MaterialHeader>
<MaterialDescription pid={pid} work={work} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import React, { FC } from "react";
import { Manifestation } from "../../../../core/utils/types/entities";
import {
hasPlayerManifestation,
hasReaderManifestation
} from "../../../reader-player/helper";
import MaterialSecondaryLink from "../generic/MaterialSecondaryLink";
import MaterialSecondaryButton from "../generic/MaterialSecondaryButton";
import { playerModalId } from "../../player-modal/helper";
import { getManifestationIsbn } from "../../../../apps/material/helper";
import { useModalButtonHandler } from "../../../../core/utils/modal";
import { useText } from "../../../../core/utils/text";
import { ButtonSize } from "../../../../core/utils/types/button";
import useReaderPlayer from "../../../../core/utils/useReaderPlayer";
import LinkButton from "../../../Buttons/LinkButton";
import { Button } from "../../../Buttons/Button";

type MaterialButtonsOnlineInternalType = {
size?: ButtonSize;
Expand All @@ -25,41 +23,109 @@ const MaterialButtonsOnlineInternal: FC<MaterialButtonsOnlineInternalType> = ({
}) => {
const t = useText();
const { open } = useModalButtonHandler();
const { type, orderId, identifier } = useReaderPlayer(manifestations);

return (
<>
{/* Todo: add logic for the reservation / loan / Read / Listen buttons here */}
const renderReaderButton = () => {
if (orderId) {
return (
<LinkButton
url={new URL(`/reader?orderid=${orderId}`, window.location.href)}
buttonType="none"
variant="filled"
size={size || "large"}
dataCy={`${dataCy}-reader`}
>
{t("onlineMaterialReaderText", {
placeholders: { "@materialType": t("ebookText") }
})}
</LinkButton>
);
}

return null;
};

{hasReaderManifestation(manifestations) && (
const renderReaderTeaserButton = () => {
if (orderId) return null;

if (identifier) {
return (
<MaterialSecondaryLink
label={t("onlineMaterialTeaserText", {
placeholders: { "@materialType": t("ebookText") }
})}
size={size || "large"}
url={
new URL(
`/reader?identifier=${getManifestationIsbn(manifestations[0])}`,
window.location.href
)
new URL(`/reader?identifier=${identifier}`, window.location.href)
}
dataCy={`${dataCy}-reader-teaser`}
/>
)}
{hasPlayerManifestation(manifestations) && (
);
}
return null;
};

const renderPlayerButton = () => {
if (orderId) {
return (
<Button
dataCy={`${dataCy}-player`}
label={t("onlineMaterialPlayerText", {
placeholders: { "@materialType": t("audiobookText") }
})}
buttonType="none"
variant="filled"
size={size || "large"}
onClick={() => open(playerModalId(orderId))}
disabled={false}
collapsible={false}
/>
);
}

return null;
};

const renderPlayerTeaserButton = () => {
if (orderId) return null;

if (identifier) {
return (
<MaterialSecondaryButton
label={t("onlineMaterialTeaserText", {
placeholders: { "@materialType": t("audiobookText") }
})}
size={size || "large"}
onClick={() => {
open(playerModalId(getManifestationIsbn(manifestations[0])));
open(playerModalId(identifier));
}}
dataCy={`${dataCy}-player-teaser`}
ariaDescribedBy={t("onlineMaterialTeaserText")}
/>
)}
</>
);
);
}
return null;
};

if (type === "reader") {
return (
<>
{renderReaderButton()}
{renderReaderTeaserButton()}
</>
);
}

if (type === "player") {
return (
<>
{renderPlayerButton()}
{renderPlayerTeaserButton()}
</>
);
}

return null;
};

export default MaterialButtonsOnlineInternal;
45 changes: 31 additions & 14 deletions src/components/material/player-modal/PlayerModal.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
import React from "react";
import React, { FC } from "react";
import Modal from "../../../core/utils/modal";
import { useText } from "../../../core/utils/text";
import Player, { PlayerType } from "../../reader-player/Player";
import { playerModalId } from "./helper";

const PlayerModal = ({ identifier, orderId }: PlayerType) => {
const PlayerModal: FC<PlayerType> = ({ identifier, orderId }) => {
const t = useText();

return (
<Modal
classNames="modal--center"
dataCy="player-modal"
// Todo: Find a better way to generate the modalId
modalId={playerModalId(identifier || orderId || "")}
screenReaderModalDescriptionText={t("playerModalDescriptionText")}
closeModalAriaLabelText={t("playerModalCloseButtonText")}
>
<Player identifier={identifier} />
</Modal>
);
if (orderId) {
return (
<Modal
classNames="modal--center"
dataCy="player-modal"
modalId={playerModalId(orderId)}
screenReaderModalDescriptionText={t("playerModalDescriptionText")}
closeModalAriaLabelText={t("playerModalCloseButtonText")}
>
<Player orderId={orderId} />
</Modal>
);
}

if (identifier) {
return (
<Modal
classNames="modal--center"
dataCy="player-modal"
modalId={playerModalId(identifier)}
screenReaderModalDescriptionText={t("playerModalDescriptionText")}
closeModalAriaLabelText={t("playerModalCloseButtonText")}
>
<Player identifier={identifier} />
</Modal>
);
}

return null;
};

export default PlayerModal;
Loading
Loading