Skip to content

Commit

Permalink
Merge pull request #321 from nulib/4576-pdf-download
Browse files Browse the repository at this point in the history
Support Alternative Items download in Work Download and Share modal
  • Loading branch information
adamjarling authored Apr 23, 2024
2 parents e43bf12 + 856c0f6 commit 90795c0
Show file tree
Hide file tree
Showing 12 changed files with 1,568 additions and 801 deletions.
3 changes: 1 addition & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@
. "$(dirname "$0")/_/husky.sh"

npm run ts-lint-commit-hook
npm run lint
# npm run lint && npm run test:ci
npm run lint && npm run test:ci
Original file line number Diff line number Diff line change
Expand Up @@ -183,20 +183,52 @@ const ShareURLActions = styled(EmbedHTMLActionRow, {
},
});

const EmbedResourcesWrapper = styled("div", {
paddingBottom: "$gr3",
});

const AlternateFormatList = styled("ul", {
listStyle: "none",
marginBlockStart: "0px",
paddingInlineStart: "0px",

"> li": {
paddingBottom: "$gr2",
},

"> li > a": {
color: "$black80",
textDecoration: "underline",

"&:hover": {
color: "$black80",
textDecoration: "none",
},
},
});

const PdfLabel = styled("span", {
paddingLeft: "$gr1",
fontSize: "$gr2",
});

export {
AlternateFormatList,
EmbedHTML,
EmbedHTMLActionRow,
EmbedLayoutPreview,
EmbedLayoutPreviewContent,
EmbedLayoutPreviewTitle,
EmbedLayoutPreviewInfoPanel,
EmbedResourcesWrapper,
EmbedViewer,
ItemActions,
ItemContent,
ItemRow,
ItemStyled,
ItemThumbnail,
LayoutImg,
PdfLabel,
ShareURL,
ShareURLActions,
};
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe("DownloadAndShare", () => {
);
expect(screen.getByText("Embed Viewer")).toBeInTheDocument();
expect(screen.getByText(embedWarningText)).toBeInTheDocument();
expect(screen.getByText("Download and Embed Images")).toBeInTheDocument();
expect(screen.getByText("Download and Embed")).toBeInTheDocument();
});

it("renders download but not embed HTML for a private, unpublished work", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ import {
ActionsDialogStyled,
Content,
} from "@/components/Work/ActionsDialog/ActionsDialog.styled";
import {
LabeledContentResource,
NULWorkManifest,
} from "@/types/components/works";
import React, { useEffect, useState } from "react";

import ActionsDialogAside from "@/components/Work/ActionsDialog/Aside";
import { Canvas } from "@iiif/presentation-3";
import EmbedImages from "./EmbedImages";
import EmbedResources from "./EmbedResources";
import EmbedViewer from "@/components/Work/ActionsDialog/DownloadAndShare/EmbedViewer";
import IIIFManifest from "./IIIFManifest";
import SharedSocial from "@/components/Shared/Social";
Expand All @@ -22,8 +26,13 @@ const DownloadAndShare: React.FC = () => {
const { workState } = useWorkState();
const { manifest, work } = workState;
const [imageCanvases, setImageCanvases] = useState<Canvas[]>([]);
const [alternateFormatItems, setAlternateFormatItems] = useState<
LabeledContentResource[]
>([]);

const router = useRouter();
const isSharedLinkPage = router.pathname.includes("/shared");

const { isUserLoggedIn, isWorkInstitution, isWorkRestricted } =
useWorkAuth(work);

Expand All @@ -36,7 +45,11 @@ const DownloadAndShare: React.FC = () => {
const imageCanvases = manifest.items.filter(
(item) => getAnnotationBodyType(item) === "Image"
);
const alternateFormatItems = manifest.rendering
? [...manifest.rendering]
: [];
setImageCanvases(imageCanvases);
setAlternateFormatItems(alternateFormatItems);
}
}, [manifest]);

Expand All @@ -62,9 +75,10 @@ const DownloadAndShare: React.FC = () => {
work={work}
/>

{imageCanvases.length > 0 && (
<EmbedImages
manifest={manifest}
{(imageCanvases.length > 0 || alternateFormatItems.length > 0) && (
<EmbedResources
manifest={manifest as NULWorkManifest}
alternateFormatItems={alternateFormatItems}
showEmbedWarning={showEmbedWarning}
work={work}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { render, screen } from "@testing-library/react";

import EmbedResources from "./EmbedResources";
import React from "react";
import { manifest } from "@/mocks/work-page/download-and-share";
import { work1 } from "@/mocks/work-page/work1";

const alternateFormatItems = manifest.rendering ? [...manifest.rendering] : [];

describe("EmbedResources", () => {
it("should render the Download and Embed section with standard images ", () => {
render(
<EmbedResources
manifest={manifest}
alternateFormatItems={[]}
showEmbedWarning={false}
work={work1}
/>
);
expect(
screen.getByRole("heading", { name: "Download and Embed" })
).toBeInTheDocument();
expect(screen.getByRole("heading", { name: "Images" })).toBeInTheDocument();

const downloadEmbedItems = screen.getByTestId("download-embed-items");

expect(downloadEmbedItems).toHaveTextContent(
"BFMF_B06_F12_006_022n_am.tif"
);
expect(downloadEmbedItems).toHaveTextContent("Download JPG");
expect(downloadEmbedItems).toHaveTextContent("Embed HTML");
expect(downloadEmbedItems).toHaveTextContent("Copy IIIF");

// Alternate Formats should not be rendered
expect(
screen.queryByRole("heading", { name: "Alternate Formats" })
).toBeNull();
});

it("should render the Download and Embed section with alternate formats. It should also include 'pdf' in the link if it's a PDF mime/type", () => {
render(
<EmbedResources
manifest={manifest}
alternateFormatItems={alternateFormatItems}
showEmbedWarning={false}
work={work1}
/>
);

expect(
screen.getByRole("heading", { name: "Alternate Formats" })
).toBeInTheDocument();
expect(screen.getByRole("link", { name: "Test PDF (pdf)" })).toBeVisible();
expect(screen.getByRole("link", { name: "Transcript XYZ" })).toBeVisible();
});
});
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import type { Canvas, IIIFExternalWebResource } from "@iiif/presentation-3";
import {
AlternateFormatList,
EmbedHTML,
EmbedHTMLActionRow,
EmbedResourcesWrapper,
ItemActions,
ItemContent,
ItemRow,
ItemStyled,
ItemThumbnail,
PdfLabel,
} from "@/components/Work/ActionsDialog/DownloadAndShare/DownloadAndShare.styled";
import type { Canvas, IIIFExternalWebResource } from "@iiif/presentation-3";
import { Label, Thumbnail } from "@samvera/clover-iiif/primitives";
import {
getAnnotationBodyType,
Expand All @@ -19,22 +22,25 @@ import Announcement from "@/components/Shared/Announcement";
import CopyText from "@/components/Shared/CopyText";
import Heading from "@/components/Heading/Heading";
import IIIFLogo from "@/components/Shared/SVG/IIIF";
import type { Manifest } from "@iiif/presentation-3";
import { NULWorkManifest } from "@/types/components/works";
import React from "react";
import SimpleSelect from "@/components/Shared/SimpleSelect.styled";
import { StyledCopyText } from "@/components/Shared/CopyText.styled";
import type { Work } from "@nulib/dcapi-types";
import { embedWarningMessage } from "./DownloadAndShare";
import { useRouter } from "next/router";
import useWorkAuth from "@/hooks/useWorkAuth";

interface EmbedImagesProps {
manifest: Manifest;
interface EmbedResourcesProps {
manifest: NULWorkManifest;
alternateFormatItems: NULWorkManifest["rendering"];
showEmbedWarning: boolean;
work: Work;
}

const EmbedImages: React.FC<EmbedImagesProps> = ({
const EmbedResources: React.FC<EmbedResourcesProps> = ({
manifest,
alternateFormatItems,
showEmbedWarning,
work,
}) => {
Expand All @@ -53,8 +59,8 @@ const EmbedImages: React.FC<EmbedImagesProps> = ({
}, [manifest]);

return (
<>
<Heading as="h3">Download and Embed Images</Heading>
<EmbedResourcesWrapper>
<Heading as="h3">Download and Embed</Heading>

{isWorkRestricted && !isSharedLinkPage && (
<Announcement>
Expand All @@ -63,21 +69,45 @@ const EmbedImages: React.FC<EmbedImagesProps> = ({
)}

{(!isWorkRestricted || isSharedLinkPage) && (
<div data-testid="download-embed-items">
{imageCanvases.map((item) => (
<Item
item={item}
key={item.id}
showEmbedWarning={showEmbedWarning}
/>
))}
</div>
<>
{alternateFormatItems && alternateFormatItems.length > 0 && (
<>
<Heading as="h4">Alternate Formats</Heading>
<AlternateFormatList>
{alternateFormatItems.map((item) => (
<li key={item.id}>
{item.label && (
<a href={item.id} target="_blank" rel="noreferrer">
<Label label={item.label} as="span" />
{/* @ts-ignore */}
{item.format?.includes("application/pdf") && (
<PdfLabel>(pdf)</PdfLabel>
)}
</a>
)}
</li>
))}
</AlternateFormatList>
</>
)}

<Heading as="h4">Images</Heading>
<div data-testid="download-embed-items">
{imageCanvases.map((item) => (
<Item
item={item}
key={item.id}
showEmbedWarning={showEmbedWarning}
/>
))}
</div>
</>
)}
</>
</EmbedResourcesWrapper>
);
};

export default EmbedImages;
export default EmbedResources;

interface ItemProps {
item: Canvas;
Expand Down Expand Up @@ -142,7 +172,7 @@ const Item: React.FC<ItemProps> = ({ item, showEmbedWarning }) => {
}" />`;

const handleDownloadClick = async (
e: React.SyntheticEvent<HTMLAnchorElement>
e: React.SyntheticEvent<HTMLButtonElement>
) => {
e.preventDefault();

Expand Down Expand Up @@ -179,9 +209,9 @@ const Item: React.FC<ItemProps> = ({ item, showEmbedWarning }) => {
{item.label && <Label label={item.label} as="span" />}
<ItemActions>
<li>
<a onClick={handleDownloadClick} href="#">
<StyledCopyText onClick={handleDownloadClick}>
Download JPG
</a>
</StyledCopyText>
</li>
<li>
<a
Expand Down
23 changes: 23 additions & 0 deletions mocks/work-page/download-and-share.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { LabeledContentResource } from "@/types/components/works";
import { workManifest1 } from "./work-manifest1";

const rendering: LabeledContentResource[] = [
{
format: "application/pdf",
id: "https://clickdimensions.com/links/TestPDFfile.pdf",
label: { en: ["Test PDF"] },
type: "Text",
},

{
format: "text/plain",
id: "https://clickdimensions.com/links/TestPDFfile2.pdf",
label: { en: ["Transcript XYZ"] },
type: "Text",
},
];

export const manifest = {
...workManifest1,
rendering,
};
Loading

0 comments on commit 90795c0

Please sign in to comment.