Skip to content

Commit

Permalink
RSDEV-286 Add an info panel to the new gallery page (#113)
Browse files Browse the repository at this point in the history
This replicates much of the same behaviour as the info panel on the
existing gallery, showing metadata and providing a primary action to
preview or edit the selected document. The main interesting addition is
a floating panel that can be swiped up on mobile, as the new gallery is
mobile friendly.
  • Loading branch information
rlamacraft authored Sep 19, 2024
1 parent a6b2c79 commit 50bcc88
Show file tree
Hide file tree
Showing 40 changed files with 2,907 additions and 699 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ public class DeploymentPropertiesController extends BaseController {
@Value("${sysadmin.delete.user}")
private String sysadminDeleteUser;

@Value("${collabora.wopi.enabled}")
private String collaboraEnabled;

@Value("${msoffice.wopi.enabled}")
private String officeOnlineEnabled;

/**
* Service to return the value of property stored in the deployment.properties file. Uses a
* whitelist strategy to only return properties that should be exposed.
Expand Down Expand Up @@ -165,6 +171,10 @@ public String getPropertyValue(@RequestParam(value = "name") String propertyName
return String.valueOf(isAsposeEnabled());
case "sysadmin.delete.user":
return sysadminDeleteUser;
case "collabora.wopi.enabled":
return collaboraEnabled;
case "msoffice.wopi.enabled":
return officeOnlineEnabled;
default:
throw new IllegalArgumentException("No property available for name: " + propertyName);
}
Expand Down
1 change: 1 addition & 0 deletions src/main/webapp/eln/gallery.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<style>
html, body, #app, #app > div, #app > div > div {
height: 100%;
overscroll-behavior: none;
}
</style>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import React from "react";
import { render, cleanup, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import NameDialog from "../NameDialog";
import { ThemeProvider } from "@mui/material/styles";
import materialTheme from "../../../../theme";

beforeEach(() => {
jest.clearAllMocks();
Expand All @@ -17,14 +19,16 @@ afterEach(cleanup);
describe("NameDialog", () => {
test("Naming a new saved search the same name as an existing saved search should be an error.", () => {
render(
<NameDialog
open={true}
setOpen={() => {}}
name="foo"
setName={() => {}}
existingNames={["foo"]}
onChange={() => {}}
/>
<ThemeProvider theme={materialTheme}>
<NameDialog
open={true}
setOpen={() => {}}
name="foo"
setName={() => {}}
existingNames={["foo"]}
onChange={() => {}}
/>
</ThemeProvider>
);

expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import SearchContext from "../../../stores/contexts/Search";
import useStores from "../../../stores/use-stores";
import { globalStyles, type Theme } from "../../../theme";
import clsx from "clsx";
import ImagePreview from "../../components/ImagePreview";
import ImagePreview from "../../../components/ImagePreview";
import { StyledMenu } from "../../../components/StyledMenu";
import Portal from "@mui/material/Portal";
import NavigateContext from "../../../stores/contexts/Navigate";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { type ComponentType, useState } from "react";
import { observer } from "mobx-react-lite";
import NoPreviewIcon from "@mui/icons-material/VisibilityOff";
import PreviewIcon from "@mui/icons-material/Visibility";
import ImagePreview from "../../ImagePreview";
import ImagePreview from "../../../../components/ImagePreview";
import { library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSpinner } from "@fortawesome/free-solid-svg-icons";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import NoValue from "../../../../components/NoValue";
import useStores from "../../../../stores/use-stores";
import { mkAlert } from "../../../../stores/contexts/Alert";
import IconButtonWithTooltip from "../../../../components/IconButtonWithTooltip";
import ImagePreview from "../../ImagePreview";
import ImagePreview from "../../../../components/ImagePreview";
import PreviewIcon from "@mui/icons-material/Visibility";
import NoPreviewIcon from "@mui/icons-material/VisibilityOff";
import PrintDialog from "../../Print/PrintDialog";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { makeMockSample } from "../../../../../stores/models/__tests__/SampleMod
import { makeMockContainer } from "../../../../../stores/models/__tests__/ContainerModel/mocking";
import "../../../../../../__mocks__/createObjectURL.js";
import "../../../../../../__mocks__/matchMedia.js";
import { ThemeProvider } from "@mui/material/styles";
import materialTheme from "../../../../../theme";

beforeEach(() => {
jest.clearAllMocks();
Expand All @@ -28,15 +30,21 @@ container1.identifiers = [mockIGSNIdentifier("container")];
describe("Identifiers section", () => {
describe("When an identifier exists", () => {
test("Identifier fields sections are rendered", () => {
const { container } = render(<IdentifiersList activeResult={sample1} />);
const { container } = render(
<ThemeProvider theme={materialTheme}>
<IdentifiersList activeResult={sample1} />
</ThemeProvider>
);
expect(container).toHaveTextContent("Required Identifier Properties");
expect(container).toHaveTextContent("Recommended Identifier Properties");
});
});
describe("When an identifier exists for container", () => {
test("Required fields are rendered", () => {
const { container } = render(
<IdentifiersList activeResult={container1} />
<ThemeProvider theme={materialTheme}>
<IdentifiersList activeResult={container1} />
</ThemeProvider>
);
expect(container).toHaveTextContent("Material Sample");
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//@flow
import React, { type Node } from "react";
import NavigateContext from "../stores/contexts/Navigate";
import NavigateContext from "../../stores/contexts/Navigate";
import * as ReactRouter from "react-router";
import { useLocation } from "react-router-dom";
import useStores from "../stores/use-stores";
import useStores from "../../stores/use-stores";

type RouterNavigationContextArgs = {|
children: Node,
Expand Down
2 changes: 1 addition & 1 deletion src/main/webapp/ui/src/Router.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { observer } from "mobx-react-lite";
import React, { type Node, type ComponentType, useEffect } from "react";
import { Routes, Route } from "react-router";
import { BrowserRouter } from "react-router-dom";
import RouterNavigationContext from "./components/RouterNavigationContext";
import RouterNavigationContext from "./Inventory/components/RouterNavigationContext";
import useStores from "./stores/use-stores";

function Router(): Node {
Expand Down
62 changes: 55 additions & 7 deletions src/main/webapp/ui/src/accentedTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ export default function createAccentedTheme(accent: AccentColor): { ... } {
saturated: linkColor,
dark: linkColor,
},
callToAction: {
main: baseTheme.palette.callToAction.main,
},
standardIcon: {
main: interactiveColor,
},
Expand Down Expand Up @@ -393,12 +396,32 @@ export default function createAccentedTheme(accent: AccentColor): { ... } {
"&:hover": {
borderColor: darken(accentedBackground, hoverDarkenCoefficient),
},
},
colorPrimary: {
border: accentedBorder,
[`&.${buttonClasses.disabled}`]: {
border: accentedBorder,
borderColor: disabledColor,
},
},
contained: {
containedCallToAction: {
border: `2px solid ${
prefersMoreContrast
? "black"
: baseTheme.palette.callToAction.main
}`,
backgroundColor: prefersMoreContrast
? "black"
: baseTheme.palette.callToAction.main,
color: baseTheme.palette.callToAction.contrastText,
"&:hover": {
borderColor: baseTheme.palette.callToAction.main,
},
[`&.${buttonClasses.disabled}`]: {
borderColor: darken(disabledColor, 0.1),
},
},
containedPrimary: {
backgroundColor: mainAccentColor,
color: contrastTextColor,
borderColor: mainAccentColor,
Expand Down Expand Up @@ -451,10 +474,23 @@ export default function createAccentedTheme(accent: AccentColor): { ... } {
// Mui applies its styles
"&:hover": {
[`& .${outlinedInputClasses.notchedOutline}`]: {
borderColor: darken(
/*
* These !importants are needed because when a className is
* applied to a TextField, it is attached to the
* .MuiFormControl-root that wraps .MuiOutlinedInput-root, so
* that would have a higher specificity than this style. As
* such, without the !important it would be impossible for a
* styled component to disable the border when not hovering,
* but keep it when hovering, as it would override all styles
* on the notched outline. With the !important, if a style
* components want to override the hover effect too, they too
* can use !important
*/
border: `${accentedBorder} !important`,
borderColor: `${darken(
accentedBackground,
hoverDarkenCoefficient
),
)} !important`,
},
},
[`&:has(.${inputAdornmentClasses.positionStart})`]: {
Expand All @@ -467,10 +503,18 @@ export default function createAccentedTheme(accent: AccentColor): { ... } {
},
[`& .${inputAdornmentClasses.root}`]: {
height: "100%",
paddingLeft: baseTheme.spacing(1.5),
paddingRight: baseTheme.spacing(1.5),
borderRight: accentedBorder,
marginRight: 0,
[`&.${inputAdornmentClasses.positionStart}`]: {
paddingLeft: baseTheme.spacing(1.5),
paddingRight: baseTheme.spacing(1.5),
borderRight: accentedBorder,
marginRight: 0,
},
[`&.${inputAdornmentClasses.positionEnd}`]: {
paddingRight: baseTheme.spacing(1.5),
paddingLeft: baseTheme.spacing(1.5),
borderLeft: accentedBorder,
marginLeft: 0,
},
[`& .${typographyClasses.root}`]: {
textTransform: "uppercase",
fontWeight: 700,
Expand Down Expand Up @@ -631,6 +675,10 @@ export default function createAccentedTheme(accent: AccentColor): { ... } {
root: {
borderBottom: accentedBorder,
},
vertical: {
borderBottom: "none",
borderRight: accentedBorder,
},
withChildren: {
borderBottom: "none",
marginTop: baseTheme.spacing(-0.5),
Expand Down
43 changes: 39 additions & 4 deletions src/main/webapp/ui/src/components/DescriptionList.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import React, { type Node, type ComponentType } from "react";
import { observer } from "mobx-react-lite";
import { makeStyles } from "tss-react/mui";
import clsx from "clsx";
import { styled } from "@mui/material/styles";

const useStyles = makeStyles()((theme, { dividers, rightAlignDds }) => ({
dl: {
Expand Down Expand Up @@ -64,17 +65,39 @@ type DescriptionListArgs = {|
|}>,
dividers?: boolean,
rightAlignDds?: boolean,
sx?: { ... },
|};

// This is used so that we can attach sx to the <dl>
const Dl = styled("dl")``;

/**
* This component provides some means for the contents to be styled using the
* MUI `sx` prop.
*
* - When `below` is true, the <dt> and <dd> have the class .below. As such,
* they can styled by passing an `sx` object that selects them:
*
* <DescriptionList
* sx={{
* "& dd.below": {
* width: "100%",
* }
* }}
* ...
* />
*
*/
function DescriptionList({
content,
dividers = false,
rightAlignDds = false,
sx,
}: DescriptionListArgs): Node {
const { classes } = useStyles({ dividers, rightAlignDds });

return (
<dl className={classes.dl}>
<Dl className={classes.dl} sx={sx}>
{content.map(
({ label, value, below = false, reducedPadding = false }) => (
<span
Expand All @@ -85,16 +108,28 @@ function DescriptionList({
reducedPadding && classes.spanReducedPadding
)}
>
<dt className={clsx(classes.dt, below && classes.dtBelow)}>
<dt
className={clsx(
classes.dt,
below && classes.dtBelow,
below && "below"
)}
>
{label}
</dt>
<dd className={clsx(classes.dd, below && classes.ddBelow)}>
<dd
className={clsx(
classes.dd,
below && classes.ddBelow,
below && "below"
)}
>
{value}
</dd>
</span>
)
)}
</dl>
</Dl>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import React, { type Node } from "react";
import "photoswipe/dist/photoswipe.css";
import { Gallery, Item } from "react-photoswipe-gallery";
import { type URL } from "../../util/types";
import { type URL } from "../util/types";
import { makeStyles } from "tss-react/mui";

const useStyles = makeStyles()(() => ({
Expand All @@ -13,7 +13,7 @@ const useStyles = makeStyles()(() => ({
},
}));

type PreviewSize = {|
export type PreviewSize = {|
width: number,
height: number,
|};
Expand All @@ -39,7 +39,7 @@ export default function ImagePreview({
options={{
showAnimationDuration: 0,
hideAnimationDuration: 0,
modal: modal,
modal,
escKey: false,
}}
withDownloadButton
Expand Down
2 changes: 1 addition & 1 deletion src/main/webapp/ui/src/components/Inputs/ImageField.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { makeStyles } from "tss-react/mui";
import { observer } from "mobx-react-lite";
import DynamicallyLoadedImageEditor from "./DynamicallyLoadedImageEditor";
import { doNotAwait } from "../../util/Util";
import ImagePreview from "../../Inventory/components/ImagePreview";
import ImagePreview from "../ImagePreview";
import NoValue from "../../components/NoValue";
import FileField from "./FileField";

Expand Down
2 changes: 1 addition & 1 deletion src/main/webapp/ui/src/components/SubmitSpinnerButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function SubmitSpinnerButton({
const { classes } = useStyles({ progress });
return (
<Button
color="primary"
color="callToAction"
onClick={onClick}
variant="contained"
disabled={disabled}
Expand Down
Loading

0 comments on commit 50bcc88

Please sign in to comment.