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

Canvas metadata #311

Merged
merged 6 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
171 changes: 135 additions & 36 deletions src/components/MetadataDisplay/MetadataDisplay.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,156 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useManifestState } from '../../context/manifest-context';
import { parseMetadata } from '@Services/iiif-parser';
import { getMetadata } from '@Services/iiif-parser';
import './MetadataDisplay.scss';

const MetadataDisplay = ({ displayTitle = true, showHeading = true }) => {
const { manifest } = useManifestState();
/**
* @param {Boolean} param0 display only Canvas metadata when set to true with other props are default
* @param {Boolean} param1 display both Manifest and Canvas metadata when set to true
* @param {Boolean} param2 hide the title in the metadata when set to false, defaults to true
* @param {Boolean} param3 hide the heading UI component when set to false, defaults to true
* @returns
*/
const MetadataDisplay = ({
displayOnlyCanvasMetadata = false,
displayAllMetadata = false,
displayTitle = true,
showHeading = true
}) => {
const { manifest, canvasIndex } = useManifestState();

const [metadata, setMetadata] = React.useState();
const [manifestMetadata, setManifestMetadata] = React.useState();
// Metadata for all Canavases in state
const [canvasesMetadata, _setCanvasesMetadata] = React.useState();
// Current Canvas metadata in state
const [canvasMetadata, setCanvasMetadata] = React.useState();
// Boolean flags set according to user props to hide/show metadata
const [showManifestMetadata, setShowManifestMetadata] = React.useState();
const [showCanvasMetadata, setShowCanvasMetadata] = React.useState();

let canvasesMetadataRef = React.useRef();
const setCanvasesMetadata = (m) => {
_setCanvasesMetadata(m);
canvasesMetadataRef.current = m;
};
/**
* On the initialization of the component read metadata from the Manifest
* and/or Canvases based on the input props and set the initial set(s) of
* metadata in the component's state
*/
React.useEffect(() => {
if (manifest) {
let parsedMetadata = parseMetadata(manifest);
if (!displayTitle) {
parsedMetadata = parsedMetadata.filter(md => md.label.toLowerCase() != 'title');
// Display Canvas metadata only when specified in the props
const showCanvas = displayOnlyCanvasMetadata || displayAllMetadata;
setShowCanvasMetadata(showCanvas);
const showManifest = !displayOnlyCanvasMetadata || displayAllMetadata;
setShowManifestMetadata(showManifest);

// Parse metadata from Manifest
const parsedMetadata = getMetadata(manifest, showCanvas);

// Set Manifest and Canvas metadata in the state variables according to props
if (showCanvas) {
setCanvasesMetadata(parsedMetadata.canvasMetadata);
setCanvasMetadataInState();
}
if (showManifest) {
let manifestMeta = parsedMetadata.manifestMetadata;
if (!displayTitle) {
manifestMeta = manifestMeta.filter(md => md.label.toLowerCase() != 'title');
}
setManifestMetadata(manifestMeta);
}
setMetadata(parsedMetadata);
}
}, [manifest]);

if (metadata && metadata.length > 0) {
return (
<div
data-testid="metadata-display"
className="ramp--metadata-display">
{showHeading && (
<div className="ramp--metadata-display-title" data-testid="metadata-display-title">
<h4>Details</h4>
</div>
)}
<div className="ramp--metadata-display-content">
{metadata.map((md, i) => {
return (
<React.Fragment key={i}>
<dt>{md.label}</dt>
<dd dangerouslySetInnerHTML={{ __html: md.value }}></dd>
</React.Fragment>
);
})
}
</div>
</div>
);
} else {
return (<div
/**
* When displaying current Canvas's metadata in the component, update the metadata
* in the component's state listening to the canvasIndex changes in the central
* state
*/
React.useEffect(() => {
if (canvasIndex >= 0 && showCanvasMetadata) {
setCanvasMetadataInState();
}
}, [canvasIndex]);

/**
* Set canvas metadata in state
*/
const setCanvasMetadataInState = () => {
let canvasData = canvasesMetadataRef.current
.filter((m) => m.canvasindex === canvasIndex)[0].metadata;
if (!displayTitle && displayOnlyCanvasMetadata) {
Dananji marked this conversation as resolved.
Show resolved Hide resolved
canvasData = canvasData.filter(md => md.label.toLowerCase() != 'title');
}
setCanvasMetadata(canvasData);
};
/**
* Distinguish whether there is any metadata to be displayed
* @returns {Boolean}
*/
const hasMetadata = () => {
return canvasMetadata?.length > 0 || manifestMetadata?.length > 0;
};

return (
<div
data-testid="metadata-display"
className="ramp--metadata-display">
<p>No valid Metadata is in the Manifest</p>
</div>);
}
{showHeading && (
<div className="ramp--metadata-display-title" data-testid="metadata-display-title">
<h4>Details</h4>
</div>
)}
{hasMetadata() && (
<div className="ramp--metadata-display-content">
{showManifestMetadata && manifestMetadata?.length > 0 && (
<React.Fragment>
{displayAllMetadata && <p>Manifest Details</p>}
Dananji marked this conversation as resolved.
Show resolved Hide resolved
{manifestMetadata.map((md, index) => {
return (
<React.Fragment key={index}>
<dt>{md.label}</dt>
<dd dangerouslySetInnerHTML={{ __html: md.value }}></dd>
</React.Fragment>
);
})}
</React.Fragment>
)}
{showCanvasMetadata && canvasMetadata?.length > 0 && (
<React.Fragment>
{displayAllMetadata && <p>Canvas Details</p>}
{canvasMetadata.map((md, index) => {
return (
<React.Fragment key={index}>
<dt>{md.label}</dt>
<dd dangerouslySetInnerHTML={{ __html: md.value }}></dd>
</React.Fragment>
);
})}
</React.Fragment>
)}
</div>
)
}
{
!hasMetadata() && (
<div
data-testid="metadata-display-message"
className="ramp--metadata-display-message">
<p>No valid Metadata is in the Manifest/Canvas(es)</p>
</div>
)
}
</div>

);
};

MetadataDisplay.propTypes = {
displayOnlyCanvasMetadata: PropTypes.bool,
displayAllMetadata: PropTypes.bool,
displayTitle: PropTypes.bool,
showHeading: PropTypes.bool,
};
Expand Down
4 changes: 3 additions & 1 deletion src/components/MetadataDisplay/MetadataDisplay.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
MetadataDisplay component, renders any available metadata in a given IIIF manifest. This component reads manifest data from central state management provided by Contexts. Thus it should be wrapped by context providers using `IIIFPlayer` which is the component in Ramp providing these out of the box.
MetadataDisplay component, renders any available metadata in a given IIIF manifest. By default it displays metadata relevant to the Manifest, and can be customized to show Canvas level metadata using the following props. This component reads manifest data from central state management provided by Contexts. Thus it should be wrapped by context providers using `IIIFPlayer` which is the component in Ramp providing these out of the box.

`MetadataDisplay` component allows the following props;
- `displayTitle`: accepts a Boolean value, which has a default value of `true` and is _not required_. This allows to hide the title in the `MetadataDisplay` component if it's included in the metadata of the IIIF manifest. In some use-cases where the title is already visible in some other part of the page, this can be used to avoid displaying the title in multiple places.
Dananji marked this conversation as resolved.
Show resolved Hide resolved
- `showHeading`: accepts a Boolean value, which has a default value of `true` and is _not required_. This enables to hide the `Details` heading on top of the component allowing to customize the user interface.
- `displayOnlyCanvasMetadata`: accepts a Boolean value, which has a default value of `false` and is _not required_. Setting this to `true` indicates Ramp to read and display metadata for the current Canvas instead of Manifest.
- `displayAllMetadata`: accepts a Boolean value, which has a default value of `false` and is _not required_. Setting this to `true` indicates Ramp to read and display metadata relevant for both current Canvas and Manifest.

To import this component from the library;

Expand Down
10 changes: 9 additions & 1 deletion src/components/MetadataDisplay/MetadataDisplay.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,19 @@
}

.ramp--metadata-display-content {
padding: 0 0 1.5rem 1.5rem;
padding: 0 1.5rem 1.5rem;
color: $primaryDarker;
max-height: 30rem;
overflow-y: auto;

p {
font-weight: normal;
padding: 0.5rem 0;
margin: 00 0 0.75rem;
color: $primaryDarker;
border-bottom: 0.1rem solid $primaryDark;
}

dt {
font-weight: bold;
}
Expand Down
Loading